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 20import platform 21 22FS_TYPE = "ext4" 23BLOCKSIZE = 4096 24 25 26def args_parse(argv): 27 parser = argparse.ArgumentParser(description='mkextimage.py') 28 29 parser.add_argument("src_dir", help="The source file for sload.") 30 parser.add_argument("device", help="The device for mkfs.") 31 parser.add_argument("mount_point", help="The filesystem mountpoint.") 32 parser.add_argument("fs_size", help="The size of filesystem.") 33 parser.add_argument("--fs_type", help="The filesystem type.") 34 parser.add_argument("--dac_config", 35 help="The path of dac config to e2fsdroid.") 36 parser.add_argument("--inode_size", help="The inode size to mke2fs.") 37 parser.add_argument("--file_context", 38 help="The path of file_context to e2fsdroid.") 39 parser.add_argument("--root_dir", help="The root dir for root image.") 40 parser.add_argument("--journal_size", help="The journal_size for mke2fs.") 41 parser.add_argument("--reserve_percent", 42 help="The reserve_percent for mke2fs.") 43 parser.add_argument("--extend_opts", nargs='+', 44 help="The extend opt for mke2fs.(not support sparse)") 45 parser.add_argument("--encrypt", help="The fscrypt support.") 46 47 args = parser.parse_known_args(argv)[0] 48 return args 49 50 51def run_cmd(cmd: str): 52 res = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, 53 stderr=subprocess.PIPE) 54 sout, serr = res.communicate() 55 56 return res.pid, res.returncode, sout, serr 57 58 59def build_run_mke2fs(args) -> int: 60 mke2fs_opts = "" 61 mke2fs_cmd = "" 62 is_data = False 63 64 if "data" in args.mount_point: 65 is_data = True 66 if args.extend_opts: 67 mke2fs_opts += " -E " + ",".join(args.extend_opts) 68 if args.inode_size: 69 mke2fs_opts += " -I " + args.inode_size 70 else: 71 mke2fs_opts += " -I " + "256" 72 if args.journal_size: 73 mke2fs_opts += " -J size=" + args.journal_size 74 elif not is_data: 75 mke2fs_opts += " -O ^has_journal" 76 if args.reserve_percent: 77 mke2fs_opts += " -m " + args.reserve_percent 78 elif not is_data: 79 mke2fs_opts += " -m 0" 80 if is_data: 81 mke2fs_opts += " -O encrypt" 82 mke2fs_opts += " -L " + args.mount_point + " -M " + args.mount_point 83 84 blocks = int(int(args.fs_size) / BLOCKSIZE) 85 mke2fs_cmd += ("mke2fs " + str(mke2fs_opts) + " -t " + FS_TYPE + " -b " 86 + str(BLOCKSIZE) + " " + args.device + " " + str(blocks)) 87 res = run_cmd(mke2fs_cmd) 88 if res[1] != 0: 89 print("info: " + mke2fs_cmd) 90 print("pid " + str(res[0]) + " ret " + str(res[1]) + "\n" + 91 res[2].decode() + res[3].decode()) 92 return res[1] 93 94 95def build_run_e2fsdroid(args) -> int: 96 if sys.platform == "linux" and platform.machine().lower() == "aarch64": 97 libselinux_path = os.path.realpath("./clang_arm64/thirdparty/selinux/") 98 libpcre2_path = os.path.realpath("./clang_arm64/thirdparty/pcre2/") 99 else: 100 libselinux_path = os.path.realpath("./clang_x64/thirdparty/selinux/") 101 libpcre2_path = os.path.realpath("./clang_x64/thirdparty/pcre2/") 102 os.environ['LD_LIBRARY_PATH'] = libselinux_path + ":" + libpcre2_path 103 104 e2fsdroid_opts = "" 105 e2fsdroid_cmd = "" 106 107 if not args.extend_opts or not "sparse" in args.extend_opts: 108 e2fsdroid_opts += " -e" 109 if args.dac_config: 110 e2fsdroid_opts += " -C " + args.dac_config 111 if args.file_context: 112 if(os.path.exists(args.file_context)): 113 e2fsdroid_opts += " -S " + args.file_context 114 115 e2fsdroid_cmd += ("e2fsdroid" + e2fsdroid_opts + " -f " + 116 args.src_dir + " -a " + args.mount_point + 117 " " + args.device) 118 res = run_cmd(e2fsdroid_cmd) 119 if res[1] != 0: 120 print("info: " + e2fsdroid_cmd) 121 print("pid " + str(res[0]) + " ret " + str(res[1]) + "\n" + 122 res[2].decode() + res[3].decode()) 123 return res[1] 124 125 126def build(args): 127 args = args_parse(args) 128 res = build_run_mke2fs(args) 129 if res != 0: 130 print("error run mke2fs errno: " + str(res)) 131 sys.exit(1) 132 res = build_run_e2fsdroid(args) 133 if res != 0: 134 print("error run e2fsdroid errno: " + str(res)) 135 os.remove(args.device) 136 sys.exit(2) 137 138 139if __name__ == '__main__': 140 build(sys.argv[1:]) 141