Merge "fastboot: add casefold/projid/compress options" am: 0a71c0e38c

Original change: https://android-review.googlesource.com/c/platform/system/core/+/1489380

Change-Id: I62ba5acab1a8ad1361793edc1e080d500f61a90c
This commit is contained in:
Jaegeuk Kim 2020-11-10 08:24:53 +00:00 committed by Automerger Merge Worker
commit dfcebcd845
4 changed files with 74 additions and 14 deletions

View file

@ -454,6 +454,8 @@ static int show_help() {
" --skip-reboot Don't reboot device after flashing.\n" " --skip-reboot Don't reboot device after flashing.\n"
" --disable-verity Sets disable-verity when flashing vbmeta.\n" " --disable-verity Sets disable-verity when flashing vbmeta.\n"
" --disable-verification Sets disable-verification when flashing vbmeta.\n" " --disable-verification Sets disable-verification when flashing vbmeta.\n"
" --fs-options=OPTION[,OPTION]\n"
" Enable filesystem features. OPTION supports casefold, projid, compress\n"
#if !defined(_WIN32) #if !defined(_WIN32)
" --wipe-and-use-fbe Enable file-based encryption, wiping userdata.\n" " --wipe-and-use-fbe Enable file-based encryption, wiping userdata.\n"
#endif #endif
@ -1581,7 +1583,7 @@ static unsigned fb_get_flash_block_size(std::string name) {
static void fb_perform_format( static void fb_perform_format(
const std::string& partition, int skip_if_not_supported, const std::string& partition, int skip_if_not_supported,
const std::string& type_override, const std::string& size_override, const std::string& type_override, const std::string& size_override,
const std::string& initial_dir) { const std::string& initial_dir, const unsigned fs_options) {
std::string partition_type, partition_size; std::string partition_type, partition_size;
struct fastboot_buffer buf; struct fastboot_buffer buf;
@ -1644,7 +1646,7 @@ static void fb_perform_format(
logicalBlkSize = fb_get_flash_block_size("logical-block-size"); logicalBlkSize = fb_get_flash_block_size("logical-block-size");
if (fs_generator_generate(gen, output.path, size, initial_dir, if (fs_generator_generate(gen, output.path, size, initial_dir,
eraseBlkSize, logicalBlkSize)) { eraseBlkSize, logicalBlkSize, fs_options)) {
die("Cannot generate image for %s", partition.c_str()); die("Cannot generate image for %s", partition.c_str());
} }
@ -1778,6 +1780,7 @@ int FastBootTool::Main(int argc, char* argv[]) {
bool skip_secondary = false; bool skip_secondary = false;
bool set_fbe_marker = false; bool set_fbe_marker = false;
bool force_flash = false; bool force_flash = false;
unsigned fs_options = 0;
int longindex; int longindex;
std::string slot_override; std::string slot_override;
std::string next_active; std::string next_active;
@ -1795,6 +1798,7 @@ int FastBootTool::Main(int argc, char* argv[]) {
{"disable-verification", no_argument, 0, 0}, {"disable-verification", no_argument, 0, 0},
{"disable-verity", no_argument, 0, 0}, {"disable-verity", no_argument, 0, 0},
{"force", no_argument, 0, 0}, {"force", no_argument, 0, 0},
{"fs-options", required_argument, 0, 0},
{"header-version", required_argument, 0, 0}, {"header-version", required_argument, 0, 0},
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
{"kernel-offset", required_argument, 0, 0}, {"kernel-offset", required_argument, 0, 0},
@ -1834,6 +1838,8 @@ int FastBootTool::Main(int argc, char* argv[]) {
g_disable_verity = true; g_disable_verity = true;
} else if (name == "force") { } else if (name == "force") {
force_flash = true; force_flash = true;
} else if (name == "fs-options") {
fs_options = ParseFsOption(optarg);
} else if (name == "header-version") { } else if (name == "header-version") {
g_boot_img_hdr.header_version = strtoul(optarg, nullptr, 0); g_boot_img_hdr.header_version = strtoul(optarg, nullptr, 0);
} else if (name == "dtb") { } else if (name == "dtb") {
@ -1990,7 +1996,7 @@ int FastBootTool::Main(int argc, char* argv[]) {
std::string partition = next_arg(&args); std::string partition = next_arg(&args);
auto format = [&](const std::string& partition) { auto format = [&](const std::string& partition) {
fb_perform_format(partition, 0, type_override, size_override, ""); fb_perform_format(partition, 0, type_override, size_override, "", fs_options);
}; };
do_for_partitions(partition, slot_override, format, true); do_for_partitions(partition, slot_override, format, true);
} else if (command == "signature") { } else if (command == "signature") {
@ -2180,10 +2186,10 @@ int FastBootTool::Main(int argc, char* argv[]) {
if (partition == "userdata" && set_fbe_marker) { if (partition == "userdata" && set_fbe_marker) {
fprintf(stderr, "setting FBE marker on initial userdata...\n"); fprintf(stderr, "setting FBE marker on initial userdata...\n");
std::string initial_userdata_dir = create_fbemarker_tmpdir(); std::string initial_userdata_dir = create_fbemarker_tmpdir();
fb_perform_format(partition, 1, partition_type, "", initial_userdata_dir); fb_perform_format(partition, 1, partition_type, "", initial_userdata_dir, fs_options);
delete_fbemarker_tmpdir(initial_userdata_dir); delete_fbemarker_tmpdir(initial_userdata_dir);
} else { } else {
fb_perform_format(partition, 1, partition_type, "", ""); fb_perform_format(partition, 1, partition_type, "", "", fs_options);
} }
} }
} }
@ -2233,3 +2239,23 @@ void FastBootTool::ParseOsVersion(boot_img_hdr_v1* hdr, const char* arg) {
} }
hdr->SetOsVersion(major, minor, patch); hdr->SetOsVersion(major, minor, patch);
} }
unsigned FastBootTool::ParseFsOption(const char* arg) {
unsigned fsOptions = 0;
std::vector<std::string> options = android::base::Split(arg, ",");
if (options.size() < 1)
syntax_error("bad options: %s", arg);
for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == "casefold")
fsOptions |= (1 << FS_OPT_CASEFOLD);
else if (options[i] == "projid")
fsOptions |= (1 << FS_OPT_PROJID);
else if (options[i] == "compress")
fsOptions |= (1 << FS_OPT_COMPRESS);
else
syntax_error("unsupported options: %s", options[i].c_str());
}
return fsOptions;
}

View file

@ -34,4 +34,5 @@ class FastBootTool {
void ParseOsPatchLevel(boot_img_hdr_v1*, const char*); void ParseOsPatchLevel(boot_img_hdr_v1*, const char*);
void ParseOsVersion(boot_img_hdr_v1*, const char*); void ParseOsVersion(boot_img_hdr_v1*, const char*);
unsigned ParseFsOption(const char*);
}; };

View file

@ -113,7 +113,7 @@ static int exec_cmd(const char* path, const char** argv, const char** envp) {
static int generate_ext4_image(const char* fileName, long long partSize, static int generate_ext4_image(const char* fileName, long long partSize,
const std::string& initial_dir, unsigned eraseBlkSize, const std::string& initial_dir, unsigned eraseBlkSize,
unsigned logicalBlkSize) { unsigned logicalBlkSize, const unsigned fsOptions) {
static constexpr int block_size = 4096; static constexpr int block_size = 4096;
const std::string exec_dir = android::base::GetExecutableDirectory(); const std::string exec_dir = android::base::GetExecutableDirectory();
@ -137,6 +137,12 @@ static int generate_ext4_image(const char* fileName, long long partSize,
mke2fs_args.push_back(ext_attr.c_str()); mke2fs_args.push_back(ext_attr.c_str());
mke2fs_args.push_back("-O"); mke2fs_args.push_back("-O");
mke2fs_args.push_back("uninit_bg"); mke2fs_args.push_back("uninit_bg");
if (fsOptions & (1 << FS_OPT_PROJID)) {
mke2fs_args.push_back("-I");
mke2fs_args.push_back("512");
}
mke2fs_args.push_back(fileName); mke2fs_args.push_back(fileName);
std::string size_str = std::to_string(partSize / block_size); std::string size_str = std::to_string(partSize / block_size);
@ -162,9 +168,9 @@ static int generate_ext4_image(const char* fileName, long long partSize,
return exec_cmd(e2fsdroid_args[0], e2fsdroid_args.data(), nullptr); return exec_cmd(e2fsdroid_args[0], e2fsdroid_args.data(), nullptr);
} }
static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir, static int generate_f2fs_image(const char* fileName, long long partSize,
unsigned /* unused */, unsigned /* unused */) const std::string& initial_dir, unsigned /* unused */,
{ unsigned /* unused */, const unsigned fsOptions) {
const std::string exec_dir = android::base::GetExecutableDirectory(); const std::string exec_dir = android::base::GetExecutableDirectory();
const std::string mkf2fs_path = exec_dir + "/make_f2fs"; const std::string mkf2fs_path = exec_dir + "/make_f2fs";
std::vector<const char*> mkf2fs_args = {mkf2fs_path.c_str()}; std::vector<const char*> mkf2fs_args = {mkf2fs_path.c_str()};
@ -174,6 +180,26 @@ static int generate_f2fs_image(const char* fileName, long long partSize, const s
mkf2fs_args.push_back(size_str.c_str()); mkf2fs_args.push_back(size_str.c_str());
mkf2fs_args.push_back("-g"); mkf2fs_args.push_back("-g");
mkf2fs_args.push_back("android"); mkf2fs_args.push_back("android");
if (fsOptions & (1 << FS_OPT_PROJID)) {
mkf2fs_args.push_back("-O");
mkf2fs_args.push_back("project_quota,extra_attr");
}
if (fsOptions & (1 << FS_OPT_CASEFOLD)) {
mkf2fs_args.push_back("-O");
mkf2fs_args.push_back("casefold");
mkf2fs_args.push_back("-C");
mkf2fs_args.push_back("utf8");
}
if (fsOptions & (1 << FS_OPT_COMPRESS)) {
mkf2fs_args.push_back("-O");
mkf2fs_args.push_back("compression");
mkf2fs_args.push_back("-O");
mkf2fs_args.push_back("extra_attr");
}
mkf2fs_args.push_back(fileName); mkf2fs_args.push_back(fileName);
mkf2fs_args.push_back(nullptr); mkf2fs_args.push_back(nullptr);
@ -198,7 +224,7 @@ static const struct fs_generator {
//returns 0 or error value //returns 0 or error value
int (*generate)(const char* fileName, long long partSize, const std::string& initial_dir, int (*generate)(const char* fileName, long long partSize, const std::string& initial_dir,
unsigned eraseBlkSize, unsigned logicalBlkSize); unsigned eraseBlkSize, unsigned logicalBlkSize, const unsigned fsOptions);
} generators[] = { } generators[] = {
{ "ext4", generate_ext4_image}, { "ext4", generate_ext4_image},
@ -215,7 +241,7 @@ const struct fs_generator* fs_get_generator(const std::string& fs_type) {
} }
int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize, int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize,
const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize) const std::string& initial_dir, unsigned eraseBlkSize,
{ unsigned logicalBlkSize, const unsigned fsOptions) {
return gen->generate(fileName, partSize, initial_dir, eraseBlkSize, logicalBlkSize); return gen->generate(fileName, partSize, initial_dir, eraseBlkSize, logicalBlkSize, fsOptions);
} }

View file

@ -5,6 +5,13 @@
struct fs_generator; struct fs_generator;
enum FS_OPTION {
FS_OPT_CASEFOLD,
FS_OPT_PROJID,
FS_OPT_COMPRESS,
};
const struct fs_generator* fs_get_generator(const std::string& fs_type); const struct fs_generator* fs_get_generator(const std::string& fs_type);
int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize, int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize,
const std::string& initial_dir, unsigned eraseBlkSize = 0, unsigned logicalBlkSize = 0); const std::string& initial_dir, unsigned eraseBlkSize = 0,
unsigned logicalBlkSize = 0, unsigned fsOptions = 0);