• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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