From 6b30509e5f9d11529b8bcadc57d82a7c6e853b42 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sat, 10 Sep 2016 10:53:11 +0200 Subject: mke2img: add buildroot wrapper --- package/mke2img/Makefile | 28 ++++++ package/mke2img/files/mke2img | 214 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 242 insertions(+) create mode 100644 package/mke2img/Makefile create mode 100755 package/mke2img/files/mke2img (limited to 'package/mke2img') diff --git a/package/mke2img/Makefile b/package/mke2img/Makefile new file mode 100644 index 000000000..83390b94d --- /dev/null +++ b/package/mke2img/Makefile @@ -0,0 +1,28 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(ADK_TOPDIR)/rules.mk + +PKG_NAME:= mke2img +PKG_VERSION:= 1 +PKG_RELEASE:= 1 +PKG_DESCR:= wrapper for ext2/3/4 filesystem utility +PKG_SECTION:= sys/fs + +NO_DISTFILES:= 1 + +PKG_CFLINE_MKE2IMG:= depends on ADK_HOST_ONLY + +include $(ADK_TOPDIR)/mk/host.mk +include $(ADK_TOPDIR)/mk/package.mk + +$(eval $(call HOST_template,MKE2IMG,mke2img,$(PKG_VERSION)-${PKG_RELEASE})) + +HOST_STYLE:= manual + +mke2img-hostinstall: + $(INSTALL_DIR) $(STAGING_HOST_DIR)/usr/bin + $(INSTALL_BIN) ./files/mke2img $(STAGING_HOST_DIR)/usr/bin + +include ${ADK_TOPDIR}/mk/host-bottom.mk +include ${ADK_TOPDIR}/mk/pkg-bottom.mk diff --git a/package/mke2img/files/mke2img b/package/mke2img/files/mke2img new file mode 100755 index 000000000..c2e0d02b7 --- /dev/null +++ b/package/mke2img/files/mke2img @@ -0,0 +1,214 @@ +#!/usr/bin/env bash + +# Buildroot wrapper to the collection of ext2/3/4 filesystem tools: +# - genext2fs, to generate ext2 filesystem images +# - tune2fs, to modify an ext2/3/4 filesystem (possibly in an image file) +# - e2fsck, to check and fix an ext2/3/4 filesystem (possibly in an image file) + +set -e + +main() { + local OPT OPTARG + local nb_blocks nb_inodes nb_res_blocks root_dir image gen rev label uuid + local -a genext2fs_opts + local -a tune2fs_opts + local tune2fs_O_opts + + # Default values + gen=2 + rev=1 + nb_extra_blocks=0 + nb_extra_inodes=0 + + while getopts :hb:B:i:I:r:d:o:G:R:l:u: OPT; do + case "${OPT}" in + h) help; exit 0;; + b) nb_blocks=${OPTARG};; + B) nb_extra_blocks=${OPTARG};; + i) nb_inodes=${OPTARG};; + I) nb_extra_inodes=${OPTARG};; + r) nb_res_blocks=${OPTARG};; + d) root_dir="${OPTARG}";; + o) image="${OPTARG}";; + G) gen=${OPTARG};; + R) rev=${OPTARG};; + l) label="${OPTARG}";; + u) uuid="${OPTARG}";; + :) error "option '%s' expects a mandatory argument\n" "${OPTARG}";; + \?) error "unknown option '%s'\n" "${OPTARG}";; + esac + done + + # Sanity checks + if [ -z "${root_dir}" ]; then + error "you must specify a root directory with '-d'\n" + fi + if [ -z "${image}" ]; then + error "you must specify an output image file with '-o'\n" + fi + case "${gen}:${rev}" in + 2:0|2:1|3:1|4:1) + ;; + 3:0|4:0) + error "revision 0 is invalid for ext3 and ext4\n" + ;; + *) error "unknown ext generation '%s' and/or revision '%s'\n" \ + "${gen}" "${rev}" + ;; + esac + + # calculate needed inodes + if [ -z "${nb_inodes}" ]; then + nb_inodes=$(find "${root_dir}" | wc -l) + nb_inodes=$((nb_inodes+400)) + fi + nb_inodes=$((nb_inodes+nb_extra_inodes)) + + # calculate needed blocks + if [ -z "${nb_blocks}" ]; then + # size ~= superblock, block+inode bitmaps, inodes (8 per block), + # blocks; we scale inodes / blocks with 10% to compensate for + # bitmaps size + slack + nb_blocks=$(du -s -k "${root_dir}" |sed -r -e 's/[[:space:]]+.*$//') + nb_blocks=$((500+(nb_blocks+nb_inodes/8)*11/10)) + if [ ${gen} -ge 3 ]; then + # we add 1300 blocks (a bit more than 1 MiB, assuming 1KiB blocks) + # for the journal + # Note: I came to 1300 blocks after trial-and-error checks. YMMV. + nb_blocks=$((nb_blocks+1300)) + fi + fi + nb_blocks=$((nb_blocks+nb_extra_blocks)) + + # Upgrade to rev1 if needed + if [ ${rev} -ge 1 ]; then + tune2fs_O_opts+=",filetype,sparse_super" + fi + + # Add a journal for ext3 and above + if [ ${gen} -ge 3 ]; then + tune2fs_opts+=( -j -J size=1 ) + fi + + # Add ext4 specific features + if [ ${gen} -ge 4 ]; then + tune2fs_O_opts+=",extents,uninit_bg,dir_index" + fi + + # Add our -O options (there will be at most one leading comma, remove it) + if [ -n "${tune2fs_O_opts}" ]; then + tune2fs_opts+=( -O "${tune2fs_O_opts#,}" ) + fi + + # Add the label if specified + if [ -n "${label}" ]; then + tune2fs_opts+=( -L "${label}" ) + fi + + # Generate the filesystem + genext2fs_opts=( -z -b ${nb_blocks} -N ${nb_inodes} -d "${root_dir}" ) + if [ -n "${nb_res_blocks}" ]; then + genext2fs_opts+=( -m ${nb_res_blocks} ) + fi + genext2fs "${genext2fs_opts[@]}" "${image}" + + # genext2fs does not generate a UUID, but fsck will whine if one + # is missing, so we need to add a UUID. + # Of course, this has to happen _before_ we run fsck. + # Also, some ext4 metadata are based on the UUID, so we must + # set it before we can convert the filesystem to ext4. + # If the user did not specify a UUID, we generate a random one. + # Although a random UUID may seem bad for reproducibility, there + # already are so many things that are not reproducible in a + # filesystem: file dates, file ordering, content of the files... + tune2fs -U "${uuid:-random}" "${image}" + + # Upgrade the filesystem + if [ ${#tune2fs_opts[@]} -ne 0 ]; then + tune2fs "${tune2fs_opts[@]}" "${image}" + fi + + # After changing filesystem options, running fsck is required + # (see: man tune2fs). Running e2fsck in other cases will ensure + # coherency of the filesystem, although it is not required. + # 'e2fsck -pDf' means: + # - automatically repair + # - optimise and check for duplicate entries + # - force checking + # Sending output to oblivion, as e2fsck can be *very* verbose, + # especially with filesystems generated by genext2fs. + # Exit codes 1 & 2 are OK, it means fs errors were successfully + # corrected, hence our little trick with $ret. + ret=0 + e2fsck -pDf "${image}" >/dev/null || ret=$? + case ${ret} in + 0|1|2) ;; + *) errorN ${ret} "failed to run e2fsck on '%s' (ext%d)\n" \ + "${image}" ${gen} + esac + printf "\n" + trace "e2fsck was successfully run on '%s' (ext%d)\n" "${image}" ${gen} + printf "\n" + + # Remove count- and time-based checks, they are not welcome + # on embedded devices, where they can cause serious boot-time + # issues by tremendously slowing down the boot. + tune2fs -c 0 -i 0 "${image}" +} + +help() { + cat <<_EOF_ +NAME + ${my_name} - Create an ext2/3/4 filesystem image + +SYNOPSIS + ${my_name} [OPTION]... + +DESCRIPTION + Create ext2/3/4 filesystem image from the content of a directory. + + -b BLOCKS + Create a filesystem of BLOCKS 1024-byte blocs. The default is to + compute the required number of blocks. + + -i INODES + Create a filesystem with INODES inodes. The default is to compute + the required number of inodes. + + -r RES_BLOCKS + Create a filesystem with RES_BLOCKS reserved blocks. The default + is to reserve 0 block. + + -d ROOT_DIR + Create a filesystem, using the content of ROOT_DIR as the content + of the root of the filesystem. Mandatory. + + -o FILE + Create the filesystem in FILE. Madatory. + + -G GEN -R REV + Create a filesystem of generation GEN (2, 3 or 4), and revision + REV (0 or 1). The default is to generate an ext2 revision 1 + filesystem; revision 0 is invalid for ext3 and ext4. + + -l LABEL + Create a filesystem with label LABEL. The default is to not set + a label. + + -u UUID + Create filesystem with uuid UUID. The default is to set a random + UUID. + + Exit status: + 0 if OK + !0 in case of error +_EOF_ +} + +trace() { local msg="${1}"; shift; printf "%s: ${msg}" "${my_name}" "${@}"; } +warn() { trace "${@}" >&2; } +errorN() { local ret="${1}"; shift; warn "${@}"; exit ${ret}; } +error() { errorN 1 "${@}"; } + +my_name="${0##*/}" +main "$@" -- cgit v1.2.3