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 22 23def args_parse(args): 24 parser = argparse.ArgumentParser(description='mkf2fsimage.py') 25 26 parser.add_argument("src_dir", help="The source file for sload.") 27 parser.add_argument("device", help="The device for mkfs.") 28 parser.add_argument("mount_point", help="The filesystem mountpoint.") 29 parser.add_argument("fs_size", help="The size of filesystem.") 30 parser.add_argument("--fs_type", help="The filesystem type.") 31 parser.add_argument("--sparse", action='store_true', 32 help="The sparse opt(not support).") 33 parser.add_argument("--prjquota", action='store_true', 34 help="The prjquota opt for mkf2fs.") 35 parser.add_argument("--casefold", action='store_true', 36 help="The casefold opt for mkf2fs.") 37 parser.add_argument("--dac_config", 38 help="The path of fs config to sload.f2fs.") 39 parser.add_argument("--timestamp", help="The timestamp for filesystem.") 40 parser.add_argument("--label", help="The label for filesystem.") 41 parser.add_argument("--file_context", 42 help="The path of file_context to sload.f2fs.") 43 parser.add_argument("--root_dir", help="The root dir for root image.") 44 parser.add_argument("--encrypt", help="The fscrypt support.") 45 46 args = parser.parse_known_args(args)[0] 47 return args 48 49 50def run_cmd(cmd: str): 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_mkf2fs(args): 59 if sys.platform == "linux" and platform.machine().lower() == "aarch64": 60 libuuid_path = os.path.realpath("./clang_arm64/thirdparty/e2fsprogs/") 61 else: 62 libuuid_path = os.path.realpath("./clang_x64/thirdparty/e2fsprogs/") 63 os.environ['LD_LIBRARY_PATH'] = libuuid_path 64 mkf2fs_opts = "" 65 mkf2fs_cmd = "" 66 67 if args.sparse: 68 mkf2fs_opts += " -S " + args.fs_size 69 if args.label: 70 mkf2fs_opts += " -l " + args.label 71 else: 72 mkf2fs_opts += " -l " + args.mount_point 73 if args.prjquota: 74 mkf2fs_opts += " -O project_quota,extra_attr" 75 if args.casefold: 76 mkf2fs_opts += " -O casefold -C utf8 " 77 78 mkf2fs_cmd += ("mkfs.f2fs -d1 -f -O encrypt -O quota -O sb_checksum" + 79 " -O verity -w 4096 -R 0:0 " + mkf2fs_opts + 80 " " + args.device) 81 82 res = run_cmd(mkf2fs_cmd) 83 if res[1] != 0: 84 print("info " + mkf2fs_cmd) 85 print("pid " + str(res[0]) + " ret " + str(res[1]) + "\n" + 86 res[2].decode() + res[3].decode()) 87 return res[1] 88 89 90def build_run_sloadf2fs(args): 91 if sys.platform == "linux" and platform.machine().lower() == "aarch64": 92 libselinux_path = os.path.realpath("./clang_arm64/thirdparty/selinux/") 93 libuuid_path = os.path.realpath("./clang_arm64/thirdparty/e2fsprogs/") 94 else: 95 libselinux_path = os.path.realpath("./clang_x64/thirdparty/selinux/") 96 libuuid_path = os.path.realpath("./clang_x64/thirdparty/e2fsprogs/") 97 os.environ['LD_LIBRARY_PATH'] = libselinux_path + ":" + libuuid_path 98 99 oldcwd = os.getcwd() 100 if sys.platform == "linux" and platform.machine().lower() == "aarch64": 101 os.chdir("./clang_arm64/thirdparty/f2fs-tools/") 102 else: 103 os.chdir("./clang_x64/thirdparty/f2fs-tools/") 104 os.chdir(oldcwd) 105 106 sloadf2fs_opts = "" 107 sloadf2fs_cmd = "" 108 109 if args.sparse: 110 sloadf2fs_opts += " -S" 111 if args.dac_config: 112 sloadf2fs_opts += " -C " + args.dac_config 113 sloadf2fs_opts += " -f " + args.src_dir 114 if args.file_context: 115 sloadf2fs_opts += " -s " + args.file_context 116 if args.mount_point[0] != '/': 117 args.mount_point = "/" + args.mount_point 118 sloadf2fs_opts += " -t " + args.mount_point 119 if args.timestamp: 120 sloadf2fs_opts += " -T " + args.timestamp 121 122 sloadf2fs_cmd += ("sload.f2fs " + sloadf2fs_opts + " " + args.device) 123 res = run_cmd(sloadf2fs_cmd) 124 if res[1] != 0: 125 print("info " + sloadf2fs_cmd) 126 print("pid " + str(res[0]) + " ret " + str(res[1]) + "\n" + 127 res[2].decode() + res[3].decode()) 128 return res[1] 129 130 131def build(args): 132 args = args_parse(args) 133 134 if not args.sparse: 135 trunc_cmd = "truncate -s " + args.fs_size + " " + args.device 136 res = run_cmd(trunc_cmd) 137 if res[1] != 0: 138 sys.exit(1) 139 res = build_run_mkf2fs(args) 140 if res != 0: 141 print("error run mkf2fs errno: " + str(res)) 142 sys.exit(2) 143 res = build_run_sloadf2fs(args) 144 if res != 0 and res != 1: 145 print("error run sload.f2fs errno: " + str(res)) 146 os.remove(args.device) 147 sys.exit(3) 148 149 150if __name__ == '__main__': 151 build(sys.argv[1:]) 152