!50 merge master into master

Add ohos fixparts func

Created-by: jiangqianrong
Commit-by: jiangqianrong
Merged-by: openharmony_ci
Description: ### 一、内容说明(相关的Issue)



### 二、建议测试周期和提测地址  
  建议测试完成时间:xxxx.xx.xx  
  投产上线时间:xxxx.xx.xx  
  提测地址:CI环境/压测环境  
  测试账号:  

### 三、变更内容
  * 3.1 关联PR列表

  * 3.2 数据库和部署说明  
    1. 常规更新 
    2. 重启unicorn
    3. 重启sidekiq
    4. 迁移任务:是否有迁移任务,没有写 "无"
    5. rake脚本:`bundle exec xxx RAILS_ENV = production`;没有写 "无"

  * 3.4 其他技术优化内容(做了什么,变更了什么)
    - 重构了 xxxx 代码
    - xxxx 算法优化


  * 3.5 废弃通知(什么字段、方法弃用?)



  * 3.6  后向不兼容变更(是否有无法向后兼容的变更?)


  
### 四、研发自测点(自测哪些?冒烟用例全部自测?)
  自测测试结论:


### 五、测试关注点(需要提醒QA重点关注的、可能会忽略的地方)
  检查点:

| 需求名称 | 是否影响xx公共模块 | 是否需要xx功能 | 需求升级是否依赖其他子产品 |
|------|------------|----------|---------------|
| xxx  | 否          | 需要       | 不需要           |
|      |            |          |               |

  接口测试:

  性能测试:

  并发测试:

  其他:



See merge request: openharmony/third_party_gptfdisk!50
This commit is contained in:
openharmony_ci
2026-03-21 19:25:53 +08:00
6 changed files with 529 additions and 1 deletions
+31
View File
@@ -47,3 +47,34 @@ ohos_executable("sgdisk") {
part_name = "gptfdisk"
install_images = [ "system" ]
}
ohos_executable("ohos_fixparts") {
install_enable = true
sources = [
"ohos/ohos_fixparts.cpp",
"ohos/ohos_mbr_helper.cpp",
]
sources += [
"basicmbr.cc",
"crc32.cc",
"diskio-unix.cc",
"diskio.cc",
"mbrpart.cc",
"support.cc",
]
include_dirs = [
".",
"//third_party/gptfdisk/",
]
public_configs = [ ":gptdisk_config" ]
external_deps = [ "e2fsprogs:libext2_uuid" ]
subsystem_name = "thirdparty"
part_name = "gptfdisk"
install_images = [ "system" ]
}
+6 -1
View File
@@ -31,10 +31,15 @@
"third_party": []
},
"build": {
"sub_component": [],
"sub_component": [
"//third_party/gptfdisk:ohos_fixparts"
],
"inner_kits": [
{
"name": "//third_party/gptfdisk:sgdisk"
},
{
"name": "//third_party/gptfdisk:ohos_fixparts"
}
],
"test": []
+227
View File
@@ -0,0 +1,227 @@
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include "ohos_fixparts.h"
#include "basicmbr.h"
#include "support.h"
#include <cstring>
#include <getopt.h>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <unistd.h>
OhosFixparts::OhosFixparts() {}
OhosFixparts::~OhosFixparts() {}
MbrResult OhosFixparts::ParseArgs(int argc, char *argv[], OhosFixpartsArgs &args)
{
int opt;
int option_index = 0;
int typecodeCount = 0; // Count of -t options
static struct option long_options[] = {{"print", no_argument, nullptr, 'p'},
{"typecode", required_argument, nullptr, 't'},
{"help", no_argument, nullptr, 'h'},
{nullptr, 0, nullptr, 0}};
while ((opt = getopt_long(argc, argv, "pt:h", long_options, &option_index)) != -1) {
switch (opt) {
case 'p':
args.printMBR = true;
break;
case 't': {
typecodeCount++;
if (typecodeCount > 1) {
std::cerr << "Error: Only one -t option is supported" << std::endl;
ShowHelp(argv[0]);
return MbrResult::ERROR_INVALID_ARGUMENT;
}
MbrResult result = ParseOption(optarg, args.partitionNum, args.typeCode);
if (result != MbrResult::SUCCESS) {
return result;
}
args.hasTypeCode = true;
break;
}
case 'h':
args.showHelp = true;
ShowHelp(argv[0]);
return MbrResult::SUCCESS;
default:
ShowHelp(argv[0]);
return MbrResult::ERROR_UNKNOWN;
}
}
// Parse device path (remaining argument)
if (optind < argc) {
args.device = argv[optind];
}
// Validate device path
if (args.device.empty()) {
std::cerr << "Device path is required" << std::endl;
ShowHelp(argv[0]);
return MbrResult::ERROR_INVALID_ARGUMENT;
}
return MbrResult::SUCCESS;
}
MbrResult OhosFixparts::ParseOption(const std::string &option, int &partitionNum, uint8_t &typeCode)
{
// Parse partition number and type code
std::string paramStr = option;
size_t colonPos = paramStr.find(':');
if (colonPos == std::string::npos || colonPos == 0 || colonPos == paramStr.length() - 1) {
std::cerr << "Invalid option format (expected partnum:typecode): " << option.c_str() << std::endl;
return MbrResult::ERROR_INVALID_ARGUMENT;
}
std::string partNumStr = paramStr.substr(0, colonPos);
std::string typeCodeStr = paramStr.substr(colonPos + 1);
MbrResult result = ParsePartNum(partNumStr, partitionNum);
if (result != MbrResult::SUCCESS) {
return result;
}
// Validate and parse type code
if (!ParseTypeCode(typeCodeStr, typeCode)) {
return MbrResult::ERROR_INVALID_ARGUMENT;
}
return MbrResult::SUCCESS;
}
MbrResult OhosFixparts::ParsePartNum(const std::string &str, int &partitionNum)
{
// Validate partition number - manual validation without exceptions
if (str.empty()) {
std::cerr << "Invalid partition number: empty string" << std::endl;
return MbrResult::ERROR_INVALID_ARGUMENT;
}
// Check if all characters are digits
for (char c : str) {
if (!isdigit(c)) {
std::cerr << "Invalid partition number (must be a pure number): " << c << std::endl;
return MbrResult::ERROR_INVALID_ARGUMENT;
}
}
// Convert to integer (safe because we validated all characters are digits)
std::istringstream iss(str);
iss >> partitionNum;
if (iss.fail() || !iss.eof()) {
std::cerr << "Parse partNum fail: fail=" << iss.fail() << ", eof=" << iss.eof() << ", str: " << str.c_str()
<< std::endl;
return MbrResult::ERROR_INVALID_ARGUMENT;
}
if (partitionNum < MIN_MBR_PARTS || partitionNum > MAX_MBR_PARTS) {
std::cerr << "Invalid partition number (must be 1-128): " << str.c_str() << std::endl;
return MbrResult::ERROR_INVALID_ARGUMENT;
}
return MbrResult::SUCCESS;
}
bool OhosFixparts::ParseTypeCode(const std::string &str, uint8_t &code)
{
unsigned int value = 0;
if (!IsHex(str)) {
std::cerr << "Invalid hex format: " << str.c_str() << std::endl;
return false;
}
// Parse hex value using std::istringstream (type-safe, no sscanf)
std::istringstream iss(str);
iss >> std::hex >> value;
if (iss.fail() || !iss.eof()) {
std::cerr << "Parse typecode fail: fail=" << iss.fail() << ", eof=" << iss.eof() << ", str: " << str.c_str()
<< std::endl;
return false;
}
// Validate range before conversion to prevent truncation
if (value < MIN_TYPE_CODE || value > MAX_TYPE_CODE) {
std::cerr << "Invalid type code (must be 0x01-0xFF): 0x" << std::hex << value << std::dec << std::endl;
return false;
}
code = static_cast<uint8_t>(value);
return true;
}
int OhosFixparts::Run(const OhosFixpartsArgs &args)
{
MbrResult result = helper_.LoadMbrData(args.device);
if (result != MbrResult::SUCCESS) {
return static_cast<int>(result);
}
// Print mode: display MBR partition table
if (args.printMBR) {
helper_.DisplayMBRData();
}
// Modify mode: change partition type code
if (args.hasTypeCode) {
std::cout << "Changing partition " << args.partitionNum << " type code to 0x" << std::hex
<< static_cast<int>(args.typeCode) << std::dec << std::endl;
result = helper_.ChangePartitionType(args.partitionNum, args.typeCode);
if (result != MbrResult::SUCCESS) {
return static_cast<int>(result);
}
result = helper_.SaveMbrData();
if (result != MbrResult::SUCCESS) {
return static_cast<int>(result);
}
std::cout << "Partition type code changed successfully." << std::endl;
}
return 0;
}
void OhosFixparts::ShowHelp(const char *programName)
{
std::cout << "Usage : " << programName << " [OPTION...] <device>" << std::endl;
std::cout << " -p, --print Print MBR partition table" << std::endl;
std::cout << " -t partnum:typecode Change partition type code" << std::endl;
std::cout << " -h, --help Show this help message" << std::endl;
std::cout << std::endl;
}
int main(int argc, char *argv[])
{
OhosFixparts fixparts;
OhosFixpartsArgs args;
MbrResult result = fixparts.ParseArgs(argc, argv, args);
if (result != MbrResult::SUCCESS) {
return static_cast<int>(result);
}
// If help was requested, exit successfully
if (args.showHelp) {
return 0;
}
return fixparts.Run(args);
}
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef OHOS_FIXPARTS_H
#define OHOS_FIXPARTS_H
#include "ohos_mbr_helper.h"
#include <string>
// Command line arguments structure
struct OhosFixpartsArgs {
std::string device; // Device path
bool printMBR; // Print MBR partition table
bool showHelp; // Show help information
bool hasTypeCode; // Flag to indicate if -t option is present
int partitionNum; // Partition number
uint8_t typeCode; // Type code
OhosFixpartsArgs() : printMBR(false), showHelp(false), hasTypeCode(false), partitionNum(-1), typeCode(0) {}
};
// Main program class
class OhosFixparts {
public:
OhosFixparts();
~OhosFixparts();
// Parse command line arguments
MbrResult ParseArgs(int argc, char *argv[], OhosFixpartsArgs &args);
// Execute partition type code modification
int Run(const OhosFixpartsArgs &args);
// Show help information
void ShowHelp(const char *programName);
private:
OhosMbrHelper helper_;
// Parse hexadecimal type code
bool ParseTypeCode(const std::string &str, uint8_t &code);
// Parse partnumber
MbrResult ParsePartNum(const std::string &str, int &partitionNum);
// Parse option string (format: partnum:typecode) and validate all parameters
MbrResult ParseOption(const std::string &option, int &partitionNum, uint8_t &typeCode);
};
#endif // OHOS_FIXPARTS_H
+144
View File
@@ -0,0 +1,144 @@
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include "ohos_mbr_helper.h"
#include <iomanip>
#include <iostream>
OhosMbrHelper::OhosMbrHelper() : mbrData_(nullptr), device_(""), loaded_(false)
{
mbrData_ = new (std::nothrow) BasicMBRData();
if (mbrData_ == nullptr) {
std::cerr << "Failed to allocate memory for MBR data" << std::endl;
loaded_ = false;
}
}
OhosMbrHelper::~OhosMbrHelper()
{
if (mbrData_ != nullptr) {
delete mbrData_;
mbrData_ = nullptr;
}
}
MbrResult OhosMbrHelper::LoadMbrData(const std::string &device)
{
// mbrData_ is initialized in constructor, no need to check here
device_ = device;
MbrResult result = ReadMbrFromDevice();
if (result != MbrResult::SUCCESS) {
return result;
}
result = ValidateMbrData();
if (result != MbrResult::SUCCESS) {
return result;
}
mbrData_->MakeItLegal();
loaded_ = true;
return MbrResult::SUCCESS;
}
MbrResult OhosMbrHelper::ReadMbrFromDevice()
{
if (!mbrData_->ReadMBRData(device_)) {
std::cerr << "Failed to read MBR data from device: " << device_ << std::endl;
return MbrResult::ERROR_READ_FAILED;
}
return MbrResult::SUCCESS;
}
MbrResult OhosMbrHelper::ValidateMbrData()
{
MBRValidity validity = mbrData_->GetValidity();
if (validity == gpt || validity == hybrid) {
std::cerr << "Device appears to be a GPT disk, not MBR" << std::endl;
return MbrResult::ERROR_GPT_PART;
}
if (validity == invalid) {
std::cerr << "Invalid MBR data on device" << std::endl;
return MbrResult::ERROR_NOT_SUPPORT_PART;
}
return MbrResult::SUCCESS;
}
MbrResult OhosMbrHelper::ChangePartitionType(int partNum, uint8_t typeCode)
{
// Check if MBR data is loaded
if (!loaded_) {
std::cerr << "MBR data not loaded. Call LoadMbrData() first." << std::endl;
return MbrResult::ERROR_READ_FAILED;
}
// Validate partition number range (1-128)
if (partNum < MIN_MBR_PARTS || partNum > MAX_MBR_PARTS) {
std::cerr << "Invalid partition number (must be 1-128): " << partNum << std::endl;
return MbrResult::ERROR_INVALID_ARGUMENT;
}
// Validate range before conversion to prevent truncation
if (typeCode < MIN_TYPE_CODE || typeCode > MAX_TYPE_CODE) {
std::cerr << "Invalid typecode (must be 0x01-0xFF): 0x" << std::hex << static_cast<int>(typeCode) << std::dec
<< std::endl;
return MbrResult::ERROR_INVALID_ARGUMENT;
}
// Check if partition exists and is not empty
if (mbrData_->GetLength(partNum - 1) == 0) {
std::cerr << "Partition " << partNum << " is empty or does not exist" << std::endl;
return MbrResult::ERROR_INVALID_ARGUMENT;
}
// Set partition type code
int result = mbrData_->SetPartType(partNum - 1, typeCode);
if (result == 0) {
std::cerr << "Failed to set type code for partition: " << partNum << std::endl;
return MbrResult::ERROR_UNKNOWN;
}
return MbrResult::SUCCESS;
}
MbrResult OhosMbrHelper::SaveMbrData()
{
if (!loaded_) {
std::cerr << "MBR data not loaded. Call LoadMbrData() first." << std::endl;
return MbrResult::ERROR_READ_FAILED;
}
if (!mbrData_->WriteMBRData()) {
std::cerr << "Failed to write MBR data to device: " << device_ << std::endl;
return MbrResult::ERROR_WRITE_FAILED;
}
mbrData_->DiskSync();
return MbrResult::SUCCESS;
}
void OhosMbrHelper::DisplayMBRData()
{
if (!loaded_) {
std::cerr << "MBR data not loaded. Call LoadMbrData() first." << std::endl;
return;
}
// Reuse existing DisplayMBRData implementation from basicmbr.cc
// This provides more comprehensive MBR information including disk size,
// disk identifier, and detailed partition information
mbrData_->DisplayMBRData();
}
+65
View File
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef OHOS_MBR_HELPER_H
#define OHOS_MBR_HELPER_H
#include <cstdint>
#include <string>
#include "basicmbr.h"
// MBR operation result codes
enum class MbrResult {
SUCCESS = 0,
ERROR_UNKNOWN = 1,
ERROR_READ_FAILED = 2,
ERROR_WRITE_FAILED = 3,
ERROR_INVALID_ARGUMENT = 4,
ERROR_NOT_SUPPORT_PART = 5,
ERROR_GPT_PART = 6
};
#define MIN_MBR_PARTS 1
#define MIN_TYPE_CODE 0x01
#define MAX_TYPE_CODE 0xFF
// MBR partition type code modifier class
class OhosMbrHelper final {
public:
OhosMbrHelper();
~OhosMbrHelper();
// Load MBR data
MbrResult LoadMbrData(const std::string &device);
// Read MBR data from device
MbrResult ReadMbrFromDevice();
// Validate MBR data
MbrResult ValidateMbrData();
// Change partition type code
// partNum: Partition number (1-128)
// typeCode: Type code (0x01-0xFF)
MbrResult ChangePartitionType(int partNum, uint8_t typeCode);
// Save MBR data to disk
MbrResult SaveMbrData();
// Display MBR partition table
void DisplayMBRData();
private:
BasicMBRData *mbrData_; // MBR data object pointer (initialized in constructor)
std::string device_;
bool loaded_;
};
#endif // OHOS_MBR_HELPER_H