2010-04-19 14:24:11 +02:00
|
|
|
#!/bin/sh
|
|
|
|
# genext2fs wrapper calculating needed blocks/inodes values if not specified
|
2013-04-11 14:17:51 +02:00
|
|
|
set -e
|
2010-04-19 14:24:11 +02:00
|
|
|
|
|
|
|
export LC_ALL=C
|
|
|
|
|
|
|
|
CALC_BLOCKS=1
|
|
|
|
CALC_INODES=1
|
2013-04-11 14:17:51 +02:00
|
|
|
EXT_OPTS=
|
|
|
|
EXT_OPTS_O=
|
2010-04-19 14:24:11 +02:00
|
|
|
|
|
|
|
while getopts x:d:D:b:i:N:m:g:e:zfqUPhVv f
|
|
|
|
do
|
|
|
|
case $f in
|
|
|
|
b) CALC_BLOCKS=0 ;;
|
2010-12-30 23:10:21 +01:00
|
|
|
N) CALC_INODES=0; INODES=$OPTARG ;;
|
2010-04-19 14:24:11 +02:00
|
|
|
d) TARGET_DIR=$OPTARG ;;
|
|
|
|
esac
|
|
|
|
done
|
2013-04-11 14:17:51 +02:00
|
|
|
eval IMG="\"\${${OPTIND}}\""
|
2010-04-19 14:24:11 +02:00
|
|
|
|
|
|
|
# calculate needed inodes
|
|
|
|
if [ $CALC_INODES -eq 1 ];
|
|
|
|
then
|
|
|
|
INODES=$(find $TARGET_DIR | wc -l)
|
|
|
|
INODES=$(expr $INODES + 400)
|
|
|
|
set -- $@ -N $INODES
|
|
|
|
fi
|
|
|
|
|
2010-12-30 23:10:21 +01:00
|
|
|
# calculate needed blocks
|
|
|
|
if [ $CALC_BLOCKS -eq 1 ];
|
|
|
|
then
|
|
|
|
# size ~= superblock, block+inode bitmaps, inodes (8 per block), blocks
|
|
|
|
# we scale inodes / blocks with 10% to compensate for bitmaps size + slack
|
|
|
|
BLOCKS=$(du -s -c -k $TARGET_DIR | grep total | sed -e "s/total//")
|
|
|
|
BLOCKS=$(expr 500 + \( $BLOCKS + $INODES / 8 \) \* 11 / 10)
|
2013-04-12 14:57:36 +02:00
|
|
|
# we add 1300 blocks (a bit more than 1 MiB, assuming 1KiB blocks) for
|
2013-04-11 14:17:51 +02:00
|
|
|
# the journal if ext3/4
|
2013-04-12 14:57:36 +02:00
|
|
|
# Note: I came to 1300 blocks after trial-and-error checks. YMMV.
|
2013-04-11 14:17:51 +02:00
|
|
|
if [ ${GEN} -ge 3 ]; then
|
2013-04-12 14:57:36 +02:00
|
|
|
BLOCKS=$(expr 1300 + $BLOCKS )
|
2013-04-11 14:17:51 +02:00
|
|
|
fi
|
2010-12-30 23:10:21 +01:00
|
|
|
set -- $@ -b $BLOCKS
|
|
|
|
fi
|
|
|
|
|
2013-04-11 14:17:51 +02:00
|
|
|
e2tunefsck() {
|
fs/ext2: further fix to the UUID
Turned out that setting a nil-UUID is no better than clearing it.
What currently happens is as follows:
- first, genext2fs does not generate a UUID
- then we tune2fs to upgrade the filesystem
- then we run fsck, which generates a random UUID
- then we re-run tune2fs to set a nil-UUID
So, on the target, if the file system is improperly unmounted (eg.
with a power failure), on next boot, fsck may be run, and a new
random UUID will be generated.
*However*, fsck improperly updates the filesystem when it adds the
UUID, and there are a few group descriptor checksum errors.
Those errors will go undetected until the next fsck, which will then
block for user input (bad on embedded systems, bad).
Fix that by systematically generating a random UUID _before_ we call
to fsck.
A random UUID is not so bad, after all, since there are already so
many sources of unpredictability in the filesystem: files date and
ordering, files content (date, paths...) which renders a fixed UUID
unneeded.
And it is still possible to set the UUID in a post-image script if
needed, anyway.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Peter Korsgaard <jacmet@uclibc.org>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
2013-05-28 14:11:37 +02:00
|
|
|
# genext2fs does not generate a UUID, but fsck will whine if one is
|
|
|
|
# is missing, so we need to add a UUID.
|
|
|
|
# Of course, this has to happend _before_ we run fsck.
|
fs/ext2: fix generation of ext4 filesystems
cset 7a58a4e (e2fsprogs: bump to version 1.42.9) broke the generation
of ext4 filesystems.
This is because, in ext4, some metadata are dependent on the UUID.
If changing the UUID of an ext4 filesystem, tune2fs now exits with
exit-code 1, and prints a message to run fsck, to avoid trashing the
filesystem.
This condition is of utmost importance on a mounted filesysten (which
is not our case) to avoid corruption (yes, it is possible to change
the UUID of a mounted filesystem).
But the error is not valid for us, since we are working on an unmonted
filesystem image in the first place.
Since we change the UUID after we convert the filesystem (to ext4),
tune2fs just bails out.
We can not just ignore the exit code of tune2fs, since we still want
to catch any other failure.
It turns out that, changing the UUID before converting the filesystem
is just the way to go.
Fixes #6752.
Reported-by: Daniel Mentz <daniel@exxm.de>
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Daniel Mentz <daniel@exxm.de>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
2014-01-05 23:56:18 +01:00
|
|
|
# Also, some ext4 metadata are based on the UUID, so we must
|
|
|
|
# set it before we can convert the filesystem to ext4.
|
fs/ext2: further fix to the UUID
Turned out that setting a nil-UUID is no better than clearing it.
What currently happens is as follows:
- first, genext2fs does not generate a UUID
- then we tune2fs to upgrade the filesystem
- then we run fsck, which generates a random UUID
- then we re-run tune2fs to set a nil-UUID
So, on the target, if the file system is improperly unmounted (eg.
with a power failure), on next boot, fsck may be run, and a new
random UUID will be generated.
*However*, fsck improperly updates the filesystem when it adds the
UUID, and there are a few group descriptor checksum errors.
Those errors will go undetected until the next fsck, which will then
block for user input (bad on embedded systems, bad).
Fix that by systematically generating a random UUID _before_ we call
to fsck.
A random UUID is not so bad, after all, since there are already so
many sources of unpredictability in the filesystem: files date and
ordering, files content (date, paths...) which renders a fixed UUID
unneeded.
And it is still possible to set the UUID in a post-image script if
needed, anyway.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Peter Korsgaard <jacmet@uclibc.org>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
2013-05-28 14:11:37 +02:00
|
|
|
# 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 random "${IMG}"
|
|
|
|
|
fs/ext2: fix generation of ext4 filesystems
cset 7a58a4e (e2fsprogs: bump to version 1.42.9) broke the generation
of ext4 filesystems.
This is because, in ext4, some metadata are dependent on the UUID.
If changing the UUID of an ext4 filesystem, tune2fs now exits with
exit-code 1, and prints a message to run fsck, to avoid trashing the
filesystem.
This condition is of utmost importance on a mounted filesysten (which
is not our case) to avoid corruption (yes, it is possible to change
the UUID of a mounted filesystem).
But the error is not valid for us, since we are working on an unmonted
filesystem image in the first place.
Since we change the UUID after we convert the filesystem (to ext4),
tune2fs just bails out.
We can not just ignore the exit code of tune2fs, since we still want
to catch any other failure.
It turns out that, changing the UUID before converting the filesystem
is just the way to go.
Fixes #6752.
Reported-by: Daniel Mentz <daniel@exxm.de>
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Daniel Mentz <daniel@exxm.de>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
2014-01-05 23:56:18 +01:00
|
|
|
# Upgrade the filesystem
|
|
|
|
if [ $# -ne 0 ]; then
|
|
|
|
tune2fs "$@" "${IMG}"
|
|
|
|
fi
|
|
|
|
|
2013-04-11 14:17:51 +02:00
|
|
|
# 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 "${IMG}" >/dev/null || ret=$?
|
|
|
|
case ${ret} in
|
|
|
|
0|1|2) ;;
|
|
|
|
*) exit ${ret};;
|
|
|
|
esac
|
|
|
|
printf "\ne2fsck was successfully run on '%s' (ext%d)\n\n" \
|
|
|
|
"${IMG##*/}" "${GEN}"
|
|
|
|
|
2013-04-11 14:17:54 +02:00
|
|
|
# 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.
|
2013-05-28 02:33:35 +02:00
|
|
|
tune2fs -c 0 -i 0 "${IMG}"
|
2013-04-11 14:17:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Check we know what generation to generate
|
2013-04-11 14:17:53 +02:00
|
|
|
case "${GEN}:${REV}" in
|
|
|
|
2:0|2:1|3:1|4:1)
|
2013-04-11 14:17:51 +02:00
|
|
|
;;
|
|
|
|
*)
|
2013-04-11 14:17:53 +02:00
|
|
|
printf "%s: unknown ext generation '%s' and/or revision '%s'\n" \
|
|
|
|
"${0##*/}" "${GEN}" "${REV}" >&2
|
2013-04-11 14:17:51 +02:00
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
2013-04-11 14:17:53 +02:00
|
|
|
# Upgrade to rev1 if needed
|
|
|
|
if [ ${REV} -ge 1 ]; then
|
|
|
|
EXT_OPTS_O="${EXT_OPTS_O},filetype"
|
|
|
|
fi
|
|
|
|
|
2013-04-11 14:17:51 +02:00
|
|
|
# Add a journal for ext3 and above
|
|
|
|
if [ ${GEN} -ge 3 ]; then
|
|
|
|
EXT_OPTS="${EXT_OPTS} -j -J size=1"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Add ext4 specific features
|
|
|
|
if [ ${GEN} -ge 4 ]; then
|
|
|
|
EXT_OPTS_O="${EXT_OPTS_O},extents,uninit_bg,dir_index"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Add our -O options (there will be at most one leading comma, remove it)
|
|
|
|
if [ -n "${EXT_OPTS_O}" ]; then
|
|
|
|
EXT_OPTS="${EXT_OPTS} -O ${EXT_OPTS_O#,}"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Generate and upgrade the filesystem
|
|
|
|
genext2fs "$@"
|
|
|
|
e2tunefsck ${EXT_OPTS}
|