# SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2020 Bootlin # Author: Joao Marcos Costa import os import shutil import subprocess """ standard test images table: Each table item is a key:value pair representing the output image name and its respective mksquashfs options. This table should be modified only when adding support for new compression algorithms. The 'default' case takes no options but the input and output names, so it must be assigned with an empty string. """ STANDARD_TABLE = { 'default' : '', 'lzo_comp_frag' : '', 'lzo_frag' : '', 'lzo_no_frag' : '', 'zstd_comp_frag' : '', 'zstd_frag' : '', 'zstd_no_frag' : '', 'gzip_comp_frag' : '', 'gzip_frag' : '', 'gzip_no_frag' : '' } """ EXTRA_TABLE: Set this table's keys and values if you want to make squashfs images with your own customized options. """ EXTRA_TABLE = {} # path to source directory used to make squashfs test images SQFS_SRC_DIR = 'sqfs_src_dir' def get_opts_list(): """ Combines fragmentation and compression options into a list of strings. opts_list's firts item is an empty string as STANDARD_TABLE's first item is the 'default' case. Returns: A list of strings whose items are formed by a compression and a fragmentation option joined by a whitespace. """ # supported compression options only comp_opts = ['-comp lzo', '-comp zstd', '-comp gzip'] # file fragmentation options frag_opts = ['-always-use-fragments', '-always-use-fragments -noF', '-no-fragments'] opts_list = [' '] for comp_opt in comp_opts: for frag_opt in frag_opts: opts_list.append(' '.join([comp_opt, frag_opt])) return opts_list def init_standard_table(): """ Initializes STANDARD_TABLE values. STANDARD_TABLE's keys are pre-defined, and init_standard_table() assigns the right value for each one of them. """ opts_list = get_opts_list() for key, value in zip(STANDARD_TABLE.keys(), opts_list): STANDARD_TABLE[key] = value def generate_file(file_name, file_size): """ Generates a file filled with 'x'. Args: file_name: the file's name. file_size: the content's length and therefore the file size. """ content = 'x' * file_size file = open(file_name, 'w') file.write(content) file.close() def generate_sqfs_src_dir(build_dir): """ Generates the source directory used to make the SquashFS images. The source directory is generated at build_dir, and it has the following structure: sqfs_src_dir/ ├── empty-dir/ ├── f1000 ├── f4096 ├── f5096 ├── subdir/ │   └── subdir-file └── sym -> subdir 3 directories, 4 files The files in the root dir. are prefixed with an 'f' followed by its size. Args: build_dir: u-boot's build-sandbox directory. """ root = os.path.join(build_dir, SQFS_SRC_DIR) # make root directory os.makedirs(root) # 4096: minimum block size file_name = 'f4096' generate_file(os.path.join(root, file_name), 4096) # 5096: minimum block size + 1000 chars (fragment) file_name = 'f5096' generate_file(os.path.join(root, file_name), 5096) # 1000: less than minimum block size (fragment only) file_name = 'f1000' generate_file(os.path.join(root, file_name), 1000) # sub-directory with a single file inside subdir_path = os.path.join(root, 'subdir') os.makedirs(subdir_path) generate_file(os.path.join(subdir_path, 'subdir-file'), 100) # symlink (target: sub-directory) os.symlink('subdir', os.path.join(root, 'sym')) # empty directory os.makedirs(os.path.join(root, 'empty-dir')) def mksquashfs(args): """ Runs mksquashfs command. Args: args: mksquashfs options (e.g.: compression and fragmentation). """ subprocess.run(['mksquashfs ' + args], shell=True, check=True, stdout=subprocess.DEVNULL) def get_mksquashfs_version(): """ Parses the output of mksquashfs -version. Returns: mksquashfs's version as a float. """ out = subprocess.run(['mksquashfs -version'], shell=True, check=True, capture_output=True, text=True) # 'out' is: mksquashfs version X (yyyy/mm/dd) ... return out.stdout.split()[2].split('.')[0:2] def check_mksquashfs_version(): """ Checks if mksquashfs meets the required version. """ version = get_mksquashfs_version(); if int(version[0]) < 4 or int(version[0]) == 4 and int(version[1]) < 4 : print('Error: mksquashfs is too old, required version: 4.4') raise AssertionError def make_all_images(build_dir): """ Makes the SquashFS images used in the test suite. The image names and respective mksquashfs options are defined in STANDARD_TABLE and EXTRA_TABLE. The destination is defined by 'build_dir'. Args: build_dir: u-boot's build-sandbox directory. """ init_standard_table() input_path = os.path.join(build_dir, SQFS_SRC_DIR) # make squashfs images according to STANDARD_TABLE for out, opts in zip(STANDARD_TABLE.keys(), STANDARD_TABLE.values()): output_path = os.path.join(build_dir, out) mksquashfs(' '.join([input_path, output_path, opts])) # make squashfs images according to EXTRA_TABLE for out, opts in zip(EXTRA_TABLE.keys(), EXTRA_TABLE.values()): output_path = os.path.join(build_dir, out) mksquashfs(' '.join([input_path, output_path, opts])) def clean_all_images(build_dir): """ Deletes the SquashFS images at build_dir. Args: build_dir: u-boot's build-sandbox directory. """ for image_name in STANDARD_TABLE: image_path = os.path.join(build_dir, image_name) os.remove(image_path) for image_name in EXTRA_TABLE: image_path = os.path.join(build_dir, image_name) os.remove(image_path) def clean_sqfs_src_dir(build_dir): """ Deletes the source directory at build_dir. Args: build_dir: u-boot's build-sandbox directory. """ path = os.path.join(build_dir, SQFS_SRC_DIR) shutil.rmtree(path)