blob: 17151bcd08ec87fe249be44ccad1cc3241050b69 [file] [log] [blame]
Simon Glass1d5006c2022-10-29 19:47:05 -06001# SPDX-License-Identifier: GPL-2.0+
2#
Simon Glass1d5006c2022-10-29 19:47:05 -06003# Copyright (c) 2018, Linaro Limited
4# Author: Takahiro Akashi <takahiro.akashi@linaro.org>
5
Simon Glassfbd95502022-10-29 19:47:06 -06006"""Helper functions for dealing with filesystems"""
7
Simon Glass1d5006c2022-10-29 19:47:05 -06008import re
9import os
10from subprocess import call, check_call, check_output, CalledProcessError
11
Simon Glass2c7b0e42022-10-29 19:47:19 -060012def mk_fs(config, fs_type, size, prefix, use_src_dir=False):
Simon Glass1d5006c2022-10-29 19:47:05 -060013 """Create a file system volume
14
15 Args:
Simon Glassfbd95502022-10-29 19:47:06 -060016 config (u_boot_config): U-Boot configuration
Simon Glass1d5006c2022-10-29 19:47:05 -060017 fs_type (str): File system type, e.g. 'ext4'
18 size (int): Size of file system in bytes
19 prefix (str): Prefix string of volume's file name
Simon Glass2c7b0e42022-10-29 19:47:19 -060020 use_src_dir (bool): true to put the file in the source directory
Simon Glassfbd95502022-10-29 19:47:06 -060021
22 Raises:
23 CalledProcessError: if any error occurs when creating the filesystem
Simon Glass1d5006c2022-10-29 19:47:05 -060024 """
Simon Glassfbd95502022-10-29 19:47:06 -060025 fs_img = f'{prefix}.{fs_type}.img'
Simon Glass2c7b0e42022-10-29 19:47:19 -060026 fs_img = os.path.join(config.source_dir if use_src_dir
27 else config.persistent_data_dir, fs_img)
Simon Glass1d5006c2022-10-29 19:47:05 -060028
29 if fs_type == 'fat16':
30 mkfs_opt = '-F 16'
31 elif fs_type == 'fat32':
32 mkfs_opt = '-F 32'
33 else:
34 mkfs_opt = ''
35
36 if re.match('fat', fs_type):
37 fs_lnxtype = 'vfat'
38 else:
39 fs_lnxtype = fs_type
40
Simon Glassfbd95502022-10-29 19:47:06 -060041 count = (size + 0x100000 - 1) // 0x100000
Simon Glass1d5006c2022-10-29 19:47:05 -060042
43 # Some distributions do not add /sbin to the default PATH, where mkfs lives
44 if '/sbin' not in os.environ["PATH"].split(os.pathsep):
45 os.environ["PATH"] += os.pathsep + '/sbin'
46
47 try:
Simon Glassfbd95502022-10-29 19:47:06 -060048 check_call(f'rm -f {fs_img}', shell=True)
49 check_call(f'dd if=/dev/zero of={fs_img} bs=1M count={count}',
50 shell=True)
51 check_call(f'mkfs.{fs_lnxtype} {mkfs_opt} {fs_img}', shell=True)
Simon Glass1d5006c2022-10-29 19:47:05 -060052 if fs_type == 'ext4':
Simon Glassfbd95502022-10-29 19:47:06 -060053 sb_content = check_output(f'tune2fs -l {fs_img}',
54 shell=True).decode()
Simon Glass1d5006c2022-10-29 19:47:05 -060055 if 'metadata_csum' in sb_content:
Simon Glassfbd95502022-10-29 19:47:06 -060056 check_call(f'tune2fs -O ^metadata_csum {fs_img}', shell=True)
Simon Glass1d5006c2022-10-29 19:47:05 -060057 return fs_img
58 except CalledProcessError:
Simon Glassfbd95502022-10-29 19:47:06 -060059 call(f'rm -f {fs_img}', shell=True)
Simon Glass1d5006c2022-10-29 19:47:05 -060060 raise
Simon Glassfbd95502022-10-29 19:47:06 -060061
62# Just for trying out
63if __name__ == "__main__":
64 import collections
65
66 CNF= collections.namedtuple('config', 'persistent_data_dir')
67
68 mk_fs(CNF('.'), 'ext4', 0x1000000, 'pref')