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