python-cryptography: bump to version 1.7.2
[buildroot-gz.git] / package / mke2img / mke2img
blobc2e0d02b7383697d92b84ab7122df2a8237f6048
1 #!/usr/bin/env bash
3 # Buildroot wrapper to the collection of ext2/3/4 filesystem tools:
4 # - genext2fs, to generate ext2 filesystem images
5 # - tune2fs, to modify an ext2/3/4 filesystem (possibly in an image file)
6 # - e2fsck, to check and fix an ext2/3/4 filesystem (possibly in an image file)
8 set -e
10 main() {
11 local OPT OPTARG
12 local nb_blocks nb_inodes nb_res_blocks root_dir image gen rev label uuid
13 local -a genext2fs_opts
14 local -a tune2fs_opts
15 local tune2fs_O_opts
17 # Default values
18 gen=2
19 rev=1
20 nb_extra_blocks=0
21 nb_extra_inodes=0
23 while getopts :hb:B:i:I:r:d:o:G:R:l:u: OPT; do
24 case "${OPT}" in
25 h) help; exit 0;;
26 b) nb_blocks=${OPTARG};;
27 B) nb_extra_blocks=${OPTARG};;
28 i) nb_inodes=${OPTARG};;
29 I) nb_extra_inodes=${OPTARG};;
30 r) nb_res_blocks=${OPTARG};;
31 d) root_dir="${OPTARG}";;
32 o) image="${OPTARG}";;
33 G) gen=${OPTARG};;
34 R) rev=${OPTARG};;
35 l) label="${OPTARG}";;
36 u) uuid="${OPTARG}";;
37 :) error "option '%s' expects a mandatory argument\n" "${OPTARG}";;
38 \?) error "unknown option '%s'\n" "${OPTARG}";;
39 esac
40 done
42 # Sanity checks
43 if [ -z "${root_dir}" ]; then
44 error "you must specify a root directory with '-d'\n"
46 if [ -z "${image}" ]; then
47 error "you must specify an output image file with '-o'\n"
49 case "${gen}:${rev}" in
50 2:0|2:1|3:1|4:1)
52 3:0|4:0)
53 error "revision 0 is invalid for ext3 and ext4\n"
55 *) error "unknown ext generation '%s' and/or revision '%s'\n" \
56 "${gen}" "${rev}"
58 esac
60 # calculate needed inodes
61 if [ -z "${nb_inodes}" ]; then
62 nb_inodes=$(find "${root_dir}" | wc -l)
63 nb_inodes=$((nb_inodes+400))
65 nb_inodes=$((nb_inodes+nb_extra_inodes))
67 # calculate needed blocks
68 if [ -z "${nb_blocks}" ]; then
69 # size ~= superblock, block+inode bitmaps, inodes (8 per block),
70 # blocks; we scale inodes / blocks with 10% to compensate for
71 # bitmaps size + slack
72 nb_blocks=$(du -s -k "${root_dir}" |sed -r -e 's/[[:space:]]+.*$//')
73 nb_blocks=$((500+(nb_blocks+nb_inodes/8)*11/10))
74 if [ ${gen} -ge 3 ]; then
75 # we add 1300 blocks (a bit more than 1 MiB, assuming 1KiB blocks)
76 # for the journal
77 # Note: I came to 1300 blocks after trial-and-error checks. YMMV.
78 nb_blocks=$((nb_blocks+1300))
81 nb_blocks=$((nb_blocks+nb_extra_blocks))
83 # Upgrade to rev1 if needed
84 if [ ${rev} -ge 1 ]; then
85 tune2fs_O_opts+=",filetype,sparse_super"
88 # Add a journal for ext3 and above
89 if [ ${gen} -ge 3 ]; then
90 tune2fs_opts+=( -j -J size=1 )
93 # Add ext4 specific features
94 if [ ${gen} -ge 4 ]; then
95 tune2fs_O_opts+=",extents,uninit_bg,dir_index"
98 # Add our -O options (there will be at most one leading comma, remove it)
99 if [ -n "${tune2fs_O_opts}" ]; then
100 tune2fs_opts+=( -O "${tune2fs_O_opts#,}" )
103 # Add the label if specified
104 if [ -n "${label}" ]; then
105 tune2fs_opts+=( -L "${label}" )
108 # Generate the filesystem
109 genext2fs_opts=( -z -b ${nb_blocks} -N ${nb_inodes} -d "${root_dir}" )
110 if [ -n "${nb_res_blocks}" ]; then
111 genext2fs_opts+=( -m ${nb_res_blocks} )
113 genext2fs "${genext2fs_opts[@]}" "${image}"
115 # genext2fs does not generate a UUID, but fsck will whine if one
116 # is missing, so we need to add a UUID.
117 # Of course, this has to happen _before_ we run fsck.
118 # Also, some ext4 metadata are based on the UUID, so we must
119 # set it before we can convert the filesystem to ext4.
120 # If the user did not specify a UUID, we generate a random one.
121 # Although a random UUID may seem bad for reproducibility, there
122 # already are so many things that are not reproducible in a
123 # filesystem: file dates, file ordering, content of the files...
124 tune2fs -U "${uuid:-random}" "${image}"
126 # Upgrade the filesystem
127 if [ ${#tune2fs_opts[@]} -ne 0 ]; then
128 tune2fs "${tune2fs_opts[@]}" "${image}"
131 # After changing filesystem options, running fsck is required
132 # (see: man tune2fs). Running e2fsck in other cases will ensure
133 # coherency of the filesystem, although it is not required.
134 # 'e2fsck -pDf' means:
135 # - automatically repair
136 # - optimise and check for duplicate entries
137 # - force checking
138 # Sending output to oblivion, as e2fsck can be *very* verbose,
139 # especially with filesystems generated by genext2fs.
140 # Exit codes 1 & 2 are OK, it means fs errors were successfully
141 # corrected, hence our little trick with $ret.
142 ret=0
143 e2fsck -pDf "${image}" >/dev/null || ret=$?
144 case ${ret} in
145 0|1|2) ;;
146 *) errorN ${ret} "failed to run e2fsck on '%s' (ext%d)\n" \
147 "${image}" ${gen}
148 esac
149 printf "\n"
150 trace "e2fsck was successfully run on '%s' (ext%d)\n" "${image}" ${gen}
151 printf "\n"
153 # Remove count- and time-based checks, they are not welcome
154 # on embedded devices, where they can cause serious boot-time
155 # issues by tremendously slowing down the boot.
156 tune2fs -c 0 -i 0 "${image}"
159 help() {
160 cat <<_EOF_
161 NAME
162 ${my_name} - Create an ext2/3/4 filesystem image
164 SYNOPSIS
165 ${my_name} [OPTION]...
167 DESCRIPTION
168 Create ext2/3/4 filesystem image from the content of a directory.
170 -b BLOCKS
171 Create a filesystem of BLOCKS 1024-byte blocs. The default is to
172 compute the required number of blocks.
174 -i INODES
175 Create a filesystem with INODES inodes. The default is to compute
176 the required number of inodes.
178 -r RES_BLOCKS
179 Create a filesystem with RES_BLOCKS reserved blocks. The default
180 is to reserve 0 block.
182 -d ROOT_DIR
183 Create a filesystem, using the content of ROOT_DIR as the content
184 of the root of the filesystem. Mandatory.
186 -o FILE
187 Create the filesystem in FILE. Madatory.
189 -G GEN -R REV
190 Create a filesystem of generation GEN (2, 3 or 4), and revision
191 REV (0 or 1). The default is to generate an ext2 revision 1
192 filesystem; revision 0 is invalid for ext3 and ext4.
194 -l LABEL
195 Create a filesystem with label LABEL. The default is to not set
196 a label.
198 -u UUID
199 Create filesystem with uuid UUID. The default is to set a random
200 UUID.
202 Exit status:
203 0 if OK
204 !0 in case of error
205 _EOF_
208 trace() { local msg="${1}"; shift; printf "%s: ${msg}" "${my_name}" "${@}"; }
209 warn() { trace "${@}" >&2; }
210 errorN() { local ret="${1}"; shift; warn "${@}"; exit ${ret}; }
211 error() { errorN 1 "${@}"; }
213 my_name="${0##*/}"
214 main "$@"