1#!/usr/bin/env python 2# coding: utf-8 3# Copyright (c) 2021 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import sys 17import argparse 18import subprocess 19import os 20 21FS_TYPE = "ext4" 22BLOCKSIZE = 4096 23 24 25def args_parse(argv): 26 parser = argparse.ArgumentParser(description='mkextimage.py') 27 28 parser.add_argument("src_dir", help="The source file for sload.") 29 parser.add_argument("device", help="The device for mkfs.") 30 parser.add_argument("mount_point", help="The filesystem mountpoint.") 31 parser.add_argument("fs_size", help="The size of filesystem.") 32 parser.add_argument("--fs_type", help="The filesystem type.") 33 parser.add_argument("--dac_config", 34 help="The path of dac config to e2fsdroid.") 35 parser.add_argument("--inode_size", help="The inode size to mke2fs.") 36 parser.add_argument("--file_context", 37 help="The path of file_context to e2fsdroid.") 38 parser.add_argument("--root_dir", help="The root dir for root image.") 39 parser.add_argument("--journal_size", help="The journal_size for mke2fs.") 40 parser.add_argument("--reserve_percent", 41 help="The reserve_percent for mke2fs.") 42 parser.add_argument("--extend_opts", nargs='+', 43 help="The extend opt for mke2fs.(not support sparse)") 44 parser.add_argument("--encrypt", help="The fscrypt support.") 45 46 args = parser.parse_known_args(argv)[0] 47 return args 48 49 50def run_cmd(cmd): 51 res = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, 52 stderr=subprocess.PIPE) 53 sout, serr = res.communicate() 54 55 return res.pid, res.returncode, sout, serr 56 57 58def build_run_mke2fs(args): 59 mke2fs_opts = "" 60 mke2fs_cmd = "" 61 is_data = False 62 63 if "data" in args.mount_point: 64 is_data = True 65 if args.extend_opts: 66 mke2fs_opts += " -E " + ",".join(args.extend_opts) 67 if args.inode_size: 68 mke2fs_opts += " -I " + args.inode_size 69 else: 70 mke2fs_opts += " -I " + "256" 71 if args.journal_size: 72 mke2fs_opts += " -J size=" + args.journal_size 73 elif not is_data: 74 mke2fs_opts += " -O ^has_journal" 75 if args.reserve_percent: 76 mke2fs_opts += " -m " + args.reserve_percent 77 elif not is_data: 78 mke2fs_opts += " -m 0" 79 if is_data: 80 mke2fs_opts += " -O encrypt" 81 mke2fs_opts += " -L " + args.mount_point + " -M " + args.mount_point 82 83 blocks = int(int(args.fs_size) / BLOCKSIZE) 84 mke2fs_cmd += ("mke2fs " + str(mke2fs_opts) + " -t " + FS_TYPE + " -b " 85 + str(BLOCKSIZE) + " " + args.device + " " + str(blocks)) 86 res = run_cmd(mke2fs_cmd) 87 if res[1] != 0: 88 print("info: " + mke2fs_cmd) 89 print("pid " + str(res[0]) + " ret " + str(res[1]) + "\n" + 90 res[2].decode() + res[3].decode()) 91 return res[1] 92 93 94def build_run_e2fsdroid(args): 95 libselinux_path = os.path.realpath("./clang_x64/thirdparty/selinux/") 96 libpcre2_path = os.path.realpath("./clang_x64/thirdparty/pcre2/") 97 os.environ['LD_LIBRARY_PATH'] = libselinux_path + ":" + libpcre2_path 98 99 e2fsdroid_opts = "" 100 e2fsdroid_cmd = "" 101 102 if not args.extend_opts or not "sparse" in args.extend_opts: 103 e2fsdroid_opts += " -e" 104 if args.dac_config: 105 e2fsdroid_opts += " -C " + args.dac_config 106 if args.file_context: 107 if(os.path.exists(args.file_context)): 108 e2fsdroid_opts += " -S " + args.file_context 109 110 e2fsdroid_cmd += ("e2fsdroid" + e2fsdroid_opts + " -f " + 111 args.src_dir + " -a " + args.mount_point + 112 " " + args.device) 113 res = run_cmd(e2fsdroid_cmd) 114 if res[1] != 0: 115 print("info: " + e2fsdroid_cmd) 116 print("pid " + str(res[0]) + " ret " + str(res[1]) + "\n" + 117 res[2].decode() + res[3].decode()) 118 return res[1] 119 120 121def build(args): 122 args = args_parse(args) 123 124 res = build_run_mke2fs(args) 125 if res != 0: 126 print("error run mke2fs errno: " + str(res)) 127 sys.exit(1) 128 res = build_run_e2fsdroid(args) 129 if res != 0: 130 print("error run e2fsdroid errno: " + str(res)) 131 os.remove(args.device) 132 sys.exit(2) 133 134 135if __name__ == '__main__': 136 build(sys.argv[1:]) 137