Loading fastboot/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,7 @@ cc_binary { "libbase", "libbootloader_message", "libcutils", "libext2_uuid", "libext4_utils", "libfs_mgr", "libhidlbase", Loading fastboot/constants.h +4 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,9 @@ #define FB_CMD_REBOOT_RECOVERY "reboot-recovery" #define FB_CMD_REBOOT_FASTBOOT "reboot-fastboot" #define FB_CMD_POWERDOWN "powerdown" #define FB_CMD_CREATE_PARTITION "create-logical-partition" #define FB_CMD_DELETE_PARTITION "delete-logical-partition" #define FB_CMD_RESIZE_PARTITION "resize-logical-partition" #define RESPONSE_OKAY "OKAY" #define RESPONSE_FAIL "FAIL" Loading @@ -53,3 +56,4 @@ #define FB_VAR_PARTITION_SIZE "partition-size" #define FB_VAR_SLOT_SUCCESSFUL "slot-successful" #define FB_VAR_SLOT_UNBOOTABLE "slot-unbootable" #define FB_VAR_IS_LOGICAL "is-logical" fastboot/device/commands.cpp +127 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ #include <android-base/unique_fd.h> #include <cutils/android_reboot.h> #include <ext4_utils/wipe.h> #include <liblp/builder.h> #include <liblp/liblp.h> #include <uuid/uuid.h> #include "constants.h" #include "fastboot_device.h" Loading @@ -37,6 +40,7 @@ using ::android::hardware::hidl_string; using ::android::hardware::boot::V1_0::BoolResult; using ::android::hardware::boot::V1_0::CommandResult; using ::android::hardware::boot::V1_0::Slot; using namespace android::fs_mgr; bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) { using VariableHandler = std::function<bool(FastbootDevice*, const std::vector<std::string>&)>; Loading @@ -54,7 +58,8 @@ bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) {FB_VAR_HAS_SLOT, GetHasSlot}, {FB_VAR_SLOT_SUCCESSFUL, GetSlotSuccessful}, {FB_VAR_SLOT_UNBOOTABLE, GetSlotUnbootable}, {FB_VAR_PARTITION_SIZE, GetPartitionSize}}; {FB_VAR_PARTITION_SIZE, GetPartitionSize}, {FB_VAR_IS_LOGICAL, GetPartitionIsLogical}}; // args[0] is command name, args[1] is variable. auto found_variable = kVariableMap.find(args[1]); Loading Loading @@ -209,3 +214,124 @@ bool RebootRecoveryHandler(FastbootDevice* device, const std::vector<std::string TEMP_FAILURE_RETRY(pause()); return status; } // Helper class for opening a handle to a MetadataBuilder and writing the new // partition table to the same place it was read. class PartitionBuilder { public: explicit PartitionBuilder(FastbootDevice* device); bool Write(); bool Valid() const { return !!builder_; } MetadataBuilder* operator->() const { return builder_.get(); } private: std::string super_device_; uint32_t slot_number_; std::unique_ptr<MetadataBuilder> builder_; }; PartitionBuilder::PartitionBuilder(FastbootDevice* device) { auto super_device = FindPhysicalPartition(LP_METADATA_PARTITION_NAME); if (!super_device) { return; } super_device_ = *super_device; std::string slot = device->GetCurrentSlot(); slot_number_ = SlotNumberForSlotSuffix(slot); builder_ = MetadataBuilder::New(super_device_, slot_number_); } bool PartitionBuilder::Write() { std::unique_ptr<LpMetadata> metadata = builder_->Export(); if (!metadata) { return false; } return UpdatePartitionTable(super_device_, *metadata.get(), slot_number_); } bool CreatePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args) { if (args.size() < 3) { return device->WriteFail("Invalid partition name and size"); } uint64_t partition_size; std::string partition_name = args[1]; if (!android::base::ParseUint(args[2].c_str(), &partition_size)) { return device->WriteFail("Invalid partition size"); } PartitionBuilder builder(device); if (!builder.Valid()) { return device->WriteFail("Could not open super partition"); } // TODO(112433293) Disallow if the name is in the physical table as well. if (builder->FindPartition(partition_name)) { return device->WriteFail("Partition already exists"); } // Make a random UUID, since they're not currently used. uuid_t uuid; char uuid_str[37]; uuid_generate_random(uuid); uuid_unparse(uuid, uuid_str); Partition* partition = builder->AddPartition(partition_name, uuid_str, 0); if (!partition) { return device->WriteFail("Failed to add partition"); } if (!builder->ResizePartition(partition, partition_size)) { builder->RemovePartition(partition_name); return device->WriteFail("Not enough space for partition"); } if (!builder.Write()) { return device->WriteFail("Failed to write partition table"); } return device->WriteOkay("Partition created"); } bool DeletePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args) { if (args.size() < 2) { return device->WriteFail("Invalid partition name and size"); } PartitionBuilder builder(device); if (!builder.Valid()) { return device->WriteFail("Could not open super partition"); } builder->RemovePartition(args[1]); if (!builder.Write()) { return device->WriteFail("Failed to write partition table"); } return device->WriteOkay("Partition deleted"); } bool ResizePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args) { if (args.size() < 3) { return device->WriteFail("Invalid partition name and size"); } uint64_t partition_size; std::string partition_name = args[1]; if (!android::base::ParseUint(args[2].c_str(), &partition_size)) { return device->WriteFail("Invalid partition size"); } PartitionBuilder builder(device); if (!builder.Valid()) { return device->WriteFail("Could not open super partition"); } Partition* partition = builder->FindPartition(partition_name); if (!partition) { return device->WriteFail("Partition does not exist"); } if (!builder->ResizePartition(partition, partition_size)) { return device->WriteFail("Not enough space to resize partition"); } if (!builder.Write()) { return device->WriteFail("Failed to write partition table"); } return device->WriteOkay("Partition resized"); } fastboot/device/commands.h +3 −0 Original line number Diff line number Diff line Loading @@ -41,3 +41,6 @@ bool RebootRecoveryHandler(FastbootDevice* device, const std::vector<std::string bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args); bool EraseHandler(FastbootDevice* device, const std::vector<std::string>& args); bool FlashHandler(FastbootDevice* device, const std::vector<std::string>& args); bool CreatePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args); bool DeletePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args); bool ResizePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args); fastboot/device/fastboot_device.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ FastbootDevice::FastbootDevice() {FB_CMD_REBOOT_RECOVERY, RebootRecoveryHandler}, {FB_CMD_ERASE, EraseHandler}, {FB_CMD_FLASH, FlashHandler}, {FB_CMD_CREATE_PARTITION, CreatePartitionHandler}, {FB_CMD_DELETE_PARTITION, DeletePartitionHandler}, {FB_CMD_RESIZE_PARTITION, ResizePartitionHandler}, }), transport_(std::make_unique<ClientUsbTransport>()), boot_control_hal_(IBootControl::getService()) {} Loading Loading
fastboot/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,7 @@ cc_binary { "libbase", "libbootloader_message", "libcutils", "libext2_uuid", "libext4_utils", "libfs_mgr", "libhidlbase", Loading
fastboot/constants.h +4 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,9 @@ #define FB_CMD_REBOOT_RECOVERY "reboot-recovery" #define FB_CMD_REBOOT_FASTBOOT "reboot-fastboot" #define FB_CMD_POWERDOWN "powerdown" #define FB_CMD_CREATE_PARTITION "create-logical-partition" #define FB_CMD_DELETE_PARTITION "delete-logical-partition" #define FB_CMD_RESIZE_PARTITION "resize-logical-partition" #define RESPONSE_OKAY "OKAY" #define RESPONSE_FAIL "FAIL" Loading @@ -53,3 +56,4 @@ #define FB_VAR_PARTITION_SIZE "partition-size" #define FB_VAR_SLOT_SUCCESSFUL "slot-successful" #define FB_VAR_SLOT_UNBOOTABLE "slot-unbootable" #define FB_VAR_IS_LOGICAL "is-logical"
fastboot/device/commands.cpp +127 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ #include <android-base/unique_fd.h> #include <cutils/android_reboot.h> #include <ext4_utils/wipe.h> #include <liblp/builder.h> #include <liblp/liblp.h> #include <uuid/uuid.h> #include "constants.h" #include "fastboot_device.h" Loading @@ -37,6 +40,7 @@ using ::android::hardware::hidl_string; using ::android::hardware::boot::V1_0::BoolResult; using ::android::hardware::boot::V1_0::CommandResult; using ::android::hardware::boot::V1_0::Slot; using namespace android::fs_mgr; bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) { using VariableHandler = std::function<bool(FastbootDevice*, const std::vector<std::string>&)>; Loading @@ -54,7 +58,8 @@ bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) {FB_VAR_HAS_SLOT, GetHasSlot}, {FB_VAR_SLOT_SUCCESSFUL, GetSlotSuccessful}, {FB_VAR_SLOT_UNBOOTABLE, GetSlotUnbootable}, {FB_VAR_PARTITION_SIZE, GetPartitionSize}}; {FB_VAR_PARTITION_SIZE, GetPartitionSize}, {FB_VAR_IS_LOGICAL, GetPartitionIsLogical}}; // args[0] is command name, args[1] is variable. auto found_variable = kVariableMap.find(args[1]); Loading Loading @@ -209,3 +214,124 @@ bool RebootRecoveryHandler(FastbootDevice* device, const std::vector<std::string TEMP_FAILURE_RETRY(pause()); return status; } // Helper class for opening a handle to a MetadataBuilder and writing the new // partition table to the same place it was read. class PartitionBuilder { public: explicit PartitionBuilder(FastbootDevice* device); bool Write(); bool Valid() const { return !!builder_; } MetadataBuilder* operator->() const { return builder_.get(); } private: std::string super_device_; uint32_t slot_number_; std::unique_ptr<MetadataBuilder> builder_; }; PartitionBuilder::PartitionBuilder(FastbootDevice* device) { auto super_device = FindPhysicalPartition(LP_METADATA_PARTITION_NAME); if (!super_device) { return; } super_device_ = *super_device; std::string slot = device->GetCurrentSlot(); slot_number_ = SlotNumberForSlotSuffix(slot); builder_ = MetadataBuilder::New(super_device_, slot_number_); } bool PartitionBuilder::Write() { std::unique_ptr<LpMetadata> metadata = builder_->Export(); if (!metadata) { return false; } return UpdatePartitionTable(super_device_, *metadata.get(), slot_number_); } bool CreatePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args) { if (args.size() < 3) { return device->WriteFail("Invalid partition name and size"); } uint64_t partition_size; std::string partition_name = args[1]; if (!android::base::ParseUint(args[2].c_str(), &partition_size)) { return device->WriteFail("Invalid partition size"); } PartitionBuilder builder(device); if (!builder.Valid()) { return device->WriteFail("Could not open super partition"); } // TODO(112433293) Disallow if the name is in the physical table as well. if (builder->FindPartition(partition_name)) { return device->WriteFail("Partition already exists"); } // Make a random UUID, since they're not currently used. uuid_t uuid; char uuid_str[37]; uuid_generate_random(uuid); uuid_unparse(uuid, uuid_str); Partition* partition = builder->AddPartition(partition_name, uuid_str, 0); if (!partition) { return device->WriteFail("Failed to add partition"); } if (!builder->ResizePartition(partition, partition_size)) { builder->RemovePartition(partition_name); return device->WriteFail("Not enough space for partition"); } if (!builder.Write()) { return device->WriteFail("Failed to write partition table"); } return device->WriteOkay("Partition created"); } bool DeletePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args) { if (args.size() < 2) { return device->WriteFail("Invalid partition name and size"); } PartitionBuilder builder(device); if (!builder.Valid()) { return device->WriteFail("Could not open super partition"); } builder->RemovePartition(args[1]); if (!builder.Write()) { return device->WriteFail("Failed to write partition table"); } return device->WriteOkay("Partition deleted"); } bool ResizePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args) { if (args.size() < 3) { return device->WriteFail("Invalid partition name and size"); } uint64_t partition_size; std::string partition_name = args[1]; if (!android::base::ParseUint(args[2].c_str(), &partition_size)) { return device->WriteFail("Invalid partition size"); } PartitionBuilder builder(device); if (!builder.Valid()) { return device->WriteFail("Could not open super partition"); } Partition* partition = builder->FindPartition(partition_name); if (!partition) { return device->WriteFail("Partition does not exist"); } if (!builder->ResizePartition(partition, partition_size)) { return device->WriteFail("Not enough space to resize partition"); } if (!builder.Write()) { return device->WriteFail("Failed to write partition table"); } return device->WriteOkay("Partition resized"); }
fastboot/device/commands.h +3 −0 Original line number Diff line number Diff line Loading @@ -41,3 +41,6 @@ bool RebootRecoveryHandler(FastbootDevice* device, const std::vector<std::string bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args); bool EraseHandler(FastbootDevice* device, const std::vector<std::string>& args); bool FlashHandler(FastbootDevice* device, const std::vector<std::string>& args); bool CreatePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args); bool DeletePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args); bool ResizePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args);
fastboot/device/fastboot_device.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ FastbootDevice::FastbootDevice() {FB_CMD_REBOOT_RECOVERY, RebootRecoveryHandler}, {FB_CMD_ERASE, EraseHandler}, {FB_CMD_FLASH, FlashHandler}, {FB_CMD_CREATE_PARTITION, CreatePartitionHandler}, {FB_CMD_DELETE_PARTITION, DeletePartitionHandler}, {FB_CMD_RESIZE_PARTITION, ResizePartitionHandler}, }), transport_(std::make_unique<ClientUsbTransport>()), boot_control_hal_(IBootControl::getService()) {} Loading