15f9996aaSopenharmony_ci#!/usr/bin/env python
25f9996aaSopenharmony_ci# coding: utf-8
35f9996aaSopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd.
45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
65f9996aaSopenharmony_ci# You may obtain a copy of the License at
75f9996aaSopenharmony_ci#
85f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
145f9996aaSopenharmony_ci# limitations under the License.
155f9996aaSopenharmony_ci
165f9996aaSopenharmony_ciimport sys
175f9996aaSopenharmony_ciimport argparse
185f9996aaSopenharmony_ciimport subprocess
195f9996aaSopenharmony_ciimport os
205f9996aaSopenharmony_ci
215f9996aaSopenharmony_ci
225f9996aaSopenharmony_cidef args_parse(args):
235f9996aaSopenharmony_ci    parser = argparse.ArgumentParser(description='mkf2fsimage.py')
245f9996aaSopenharmony_ci
255f9996aaSopenharmony_ci    parser.add_argument("src_dir", help="The source file for sload.")
265f9996aaSopenharmony_ci    parser.add_argument("device", help="The device for mkfs.")
275f9996aaSopenharmony_ci    parser.add_argument("mount_point", help="The filesystem mountpoint.")
285f9996aaSopenharmony_ci    parser.add_argument("fs_size", help="The size of filesystem.")
295f9996aaSopenharmony_ci    parser.add_argument("--fs_type", help="The filesystem type.")
305f9996aaSopenharmony_ci    parser.add_argument("--sparse", action='store_true',
315f9996aaSopenharmony_ci                        help="The sparse opt(not support).")
325f9996aaSopenharmony_ci    parser.add_argument("--prjquota", action='store_true',
335f9996aaSopenharmony_ci                        help="The prjquota opt for mkf2fs.")
345f9996aaSopenharmony_ci    parser.add_argument("--casefold", action='store_true',
355f9996aaSopenharmony_ci                        help="The casefold opt for mkf2fs.")
365f9996aaSopenharmony_ci    parser.add_argument("--dac_config",
375f9996aaSopenharmony_ci                        help="The path of fs config to sload.f2fs.")
385f9996aaSopenharmony_ci    parser.add_argument("--timestamp", help="The timestamp for filesystem.")
395f9996aaSopenharmony_ci    parser.add_argument("--label", help="The label for filesystem.")
405f9996aaSopenharmony_ci    parser.add_argument("--file_context",
415f9996aaSopenharmony_ci                        help="The path of file_context to sload.f2fs.")
425f9996aaSopenharmony_ci    parser.add_argument("--root_dir", help="The root dir for root image.")
435f9996aaSopenharmony_ci    parser.add_argument("--encrypt", help="The fscrypt support.")
445f9996aaSopenharmony_ci
455f9996aaSopenharmony_ci    args = parser.parse_known_args(args)[0]
465f9996aaSopenharmony_ci    return args
475f9996aaSopenharmony_ci
485f9996aaSopenharmony_ci
495f9996aaSopenharmony_cidef run_cmd(cmd: str):
505f9996aaSopenharmony_ci    res = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE,
515f9996aaSopenharmony_ci                           stderr=subprocess.PIPE)
525f9996aaSopenharmony_ci    sout, serr = res.communicate()
535f9996aaSopenharmony_ci
545f9996aaSopenharmony_ci    return res.pid, res.returncode, sout, serr
555f9996aaSopenharmony_ci
565f9996aaSopenharmony_ci
575f9996aaSopenharmony_cidef build_run_mkf2fs(args):
585f9996aaSopenharmony_ci    libuuid_path = os.path.realpath("./clang_x64/thirdparty/e2fsprogs/")
595f9996aaSopenharmony_ci    os.environ['LD_LIBRARY_PATH'] = libuuid_path
605f9996aaSopenharmony_ci    mkf2fs_opts = ""
615f9996aaSopenharmony_ci    mkf2fs_cmd = ""
625f9996aaSopenharmony_ci
635f9996aaSopenharmony_ci    if args.sparse:
645f9996aaSopenharmony_ci        mkf2fs_opts += " -S " + args.fs_size
655f9996aaSopenharmony_ci    if args.label:
665f9996aaSopenharmony_ci        mkf2fs_opts += " -l " + args.label
675f9996aaSopenharmony_ci    else:
685f9996aaSopenharmony_ci        mkf2fs_opts += " -l " + args.mount_point
695f9996aaSopenharmony_ci    if args.prjquota:
705f9996aaSopenharmony_ci        mkf2fs_opts += " -O project_quota,extra_attr"
715f9996aaSopenharmony_ci    if args.casefold:
725f9996aaSopenharmony_ci        mkf2fs_opts += " -O casefold -C utf8 "
735f9996aaSopenharmony_ci
745f9996aaSopenharmony_ci    mkf2fs_cmd += ("mkfs.f2fs -d1 -f -O encrypt -O quota -O sb_checksum" +
755f9996aaSopenharmony_ci                   " -O verity -w 4096 -R 0:0 " + mkf2fs_opts +
765f9996aaSopenharmony_ci                   " " + args.device)
775f9996aaSopenharmony_ci
785f9996aaSopenharmony_ci    res = run_cmd(mkf2fs_cmd)
795f9996aaSopenharmony_ci    if res[1] != 0:
805f9996aaSopenharmony_ci        print("info " + mkf2fs_cmd)
815f9996aaSopenharmony_ci        print("pid " + str(res[0]) + " ret " + str(res[1]) + "\n" +
825f9996aaSopenharmony_ci              res[2].decode() + res[3].decode())
835f9996aaSopenharmony_ci    return res[1]
845f9996aaSopenharmony_ci
855f9996aaSopenharmony_ci
865f9996aaSopenharmony_cidef build_run_sloadf2fs(args):
875f9996aaSopenharmony_ci    libselinux_path = os.path.realpath("./clang_x64/thirdparty/selinux/")
885f9996aaSopenharmony_ci    libuuid_path = os.path.realpath("./clang_x64/thirdparty/e2fsprogs/")
895f9996aaSopenharmony_ci    os.environ['LD_LIBRARY_PATH'] = libselinux_path + ":" + libuuid_path
905f9996aaSopenharmony_ci
915f9996aaSopenharmony_ci    oldcwd = os.getcwd()
925f9996aaSopenharmony_ci    os.chdir("./clang_x64/thirdparty/f2fs-tools/")
935f9996aaSopenharmony_ci    os.chdir(oldcwd)
945f9996aaSopenharmony_ci
955f9996aaSopenharmony_ci    sloadf2fs_opts = ""
965f9996aaSopenharmony_ci    sloadf2fs_cmd = ""
975f9996aaSopenharmony_ci
985f9996aaSopenharmony_ci    if args.sparse:
995f9996aaSopenharmony_ci        sloadf2fs_opts += " -S"
1005f9996aaSopenharmony_ci    if args.dac_config:
1015f9996aaSopenharmony_ci        sloadf2fs_opts += " -C " + args.dac_config
1025f9996aaSopenharmony_ci    sloadf2fs_opts += " -f " + args.src_dir
1035f9996aaSopenharmony_ci    if args.file_context:
1045f9996aaSopenharmony_ci        sloadf2fs_opts += " -s " + args.file_context
1055f9996aaSopenharmony_ci    if args.mount_point[0] != '/':
1065f9996aaSopenharmony_ci        args.mount_point = "/" + args.mount_point
1075f9996aaSopenharmony_ci    sloadf2fs_opts += " -t " + args.mount_point
1085f9996aaSopenharmony_ci    if args.timestamp:
1095f9996aaSopenharmony_ci        sloadf2fs_opts += " -T " + args.timestamp
1105f9996aaSopenharmony_ci
1115f9996aaSopenharmony_ci    sloadf2fs_cmd += ("sload.f2fs " + sloadf2fs_opts + " " + args.device)
1125f9996aaSopenharmony_ci    res = run_cmd(sloadf2fs_cmd)
1135f9996aaSopenharmony_ci    if res[1] != 0:
1145f9996aaSopenharmony_ci        print("info " + sloadf2fs_cmd)
1155f9996aaSopenharmony_ci        print("pid " + str(res[0]) + " ret " + str(res[1]) + "\n" +
1165f9996aaSopenharmony_ci              res[2].decode() + res[3].decode())
1175f9996aaSopenharmony_ci    return res[1]
1185f9996aaSopenharmony_ci
1195f9996aaSopenharmony_ci
1205f9996aaSopenharmony_cidef build(args):
1215f9996aaSopenharmony_ci    args = args_parse(args)
1225f9996aaSopenharmony_ci
1235f9996aaSopenharmony_ci    if not args.sparse:
1245f9996aaSopenharmony_ci        trunc_cmd = "truncate -s " + args.fs_size + " " + args.device
1255f9996aaSopenharmony_ci        res = run_cmd(trunc_cmd)
1265f9996aaSopenharmony_ci        if res[1] != 0:
1275f9996aaSopenharmony_ci            sys.exit(1)
1285f9996aaSopenharmony_ci    res = build_run_mkf2fs(args)
1295f9996aaSopenharmony_ci    if res != 0:
1305f9996aaSopenharmony_ci        print("error run mkf2fs errno: " + str(res))
1315f9996aaSopenharmony_ci        sys.exit(2)
1325f9996aaSopenharmony_ci    res = build_run_sloadf2fs(args)
1335f9996aaSopenharmony_ci    if res != 0 and res != 1:
1345f9996aaSopenharmony_ci        print("error run sload.f2fs errno: " + str(res))
1355f9996aaSopenharmony_ci        os.remove(args.device)
1365f9996aaSopenharmony_ci        sys.exit(3)
1375f9996aaSopenharmony_ci
1385f9996aaSopenharmony_ci
1395f9996aaSopenharmony_ciif __name__ == '__main__':
1405f9996aaSopenharmony_ci    build(sys.argv[1:])
141