summaryrefslogtreecommitdiffstats
path: root/tests/util
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 16:29:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 16:29:51 +0000
commit6e7a315eb67cb6c113cf37e1d66c4f11a51a2b3e (patch)
tree32451fa3cdd9321fb2591fada9891b2cb70a9cd1 /tests/util
parentInitial commit. (diff)
downloadgrub2-3e86199209a10ed6555e30b8b71884cb7cc45ed2.tar.xz
grub2-3e86199209a10ed6555e30b8b71884cb7cc45ed2.zip
Adding upstream version 2.06.upstream/2.06upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/util')
-rw-r--r--tests/util/grub-fs-tester.in1572
-rw-r--r--tests/util/grub-shell-tester.in106
-rw-r--r--tests/util/grub-shell.in517
3 files changed, 2195 insertions, 0 deletions
diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in
new file mode 100644
index 0000000..bfc425e
--- /dev/null
+++ b/tests/util/grub-fs-tester.in
@@ -0,0 +1,1572 @@
+#!@BUILD_SHEBANG@
+
+set -e
+
+fs="$1"
+
+GRUBFSTEST="@builddir@/grub-fstest"
+
+tempdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+
+# This wrapper is to ease insertion of valgrind or time statistics
+run_it () {
+ LC_ALL=C "$GRUBFSTEST" "$@"
+}
+
+range() {
+ range_counter="$1"
+ while test "$range_counter" -le "$2"; do
+ echo "$range_counter"
+ range_counter="$((range_counter + $3))"
+ done
+}
+
+powrange() {
+ range_counter="$1"
+ while test "$range_counter" -le "$2"; do
+ echo "$range_counter"
+ range_counter="$((range_counter * 2))"
+ done
+}
+
+run_grubfstest () {
+ need_images=
+ for i in $(range 0 $((NEED_IMAGES_N-1)) 1); do
+ need_images="$need_images $FSIMAGEP${i}.img";
+ done
+
+ run_it -c $NEED_IMAGES_N $need_images "$@"
+}
+
+# OS LIMITATION: GNU/Linux has no AFS support, so we use a premade image and a reference tar file. I.a. no multiblocksize test
+
+MINLOGSECSIZE=9
+MAXLOGSECSIZE=9
+case x"$fs" in
+ xntfs*)
+ MINLOGSECSIZE=8
+ MAXLOGSECSIZE=12;;
+ xvfat*|xmsdos*)
+ MINLOGSECSIZE=9
+ # OS LIMITATION: It could go up to 32768 but Linux rejects sector sizes > 4096
+ MAXLOGSECSIZE=12;;
+ xext*)
+ MINLOGSECSIZE=8
+ MAXLOGSECSIZE=12;;
+ xbtrfs*)
+ MINLOGSECSIZE=8
+ # OS LIMITATION: It could go up to 32768 but Linux rejects sector sizes > 4096
+ MAXLOGSECSIZE=12;;
+ xxfs)
+ MINLOGSECSIZE=9
+ # OS LIMITATION: GNU/Linux doesn't accept > 4096
+ MAXLOGSECSIZE=12;;
+ xxfs_crc)
+ MINLOGSECSIZE=9
+ # OS LIMITATION: GNU/Linux doesn't accept > 1024
+ MAXLOGSECSIZE=10;;
+ xzfs*)
+ # OS LIMITATION: zfs-fuse hangs when creating zpool with sectors <=256B.
+ MINLOGSECSIZE=9
+ # OS LIMITATION: zfs-fuse fails with >= 32K sectors.
+ # OS limitation: zfs-fuse always uses ashift=9 with loop devices
+ MAXLOGSECSIZE=9;;
+esac
+for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do
+ SECSIZE="$((1 << LOGSECSIZE))"
+ MINBLKSIZE=512
+ MAXBLKSIZE=512
+ BLKSTEP=0
+ case x"$fs" in
+ xntfs*)
+ MINBLKSIZE=$SECSIZE
+ MAXBLKSIZE=65536
+ if [ x"$SECSIZE" = x256 ]; then
+ MINBLKSIZE=512
+ MAXBLKSIZE=32768
+ fi
+ ;;
+ xvfat* | xmsdos*)
+ MINBLKSIZE=$SECSIZE
+ MAXBLKSIZE=$((128*SECSIZE))
+ ;;
+ xexfat*)
+ MINBLKSIZE=$SECSIZE
+ # It could go further but it requires more and more space
+ MAXBLKSIZE=8286208
+ ;;
+ xhfs)
+ MINBLKSIZE=512
+ # OS LIMITATION: should be 1048576 but linux hangs on unmnount with
+ # >= 524288
+ MAXBLKSIZE=262144
+ ;;
+ xhfsplus | xhfsplus_casesens | xhfsplus_wrap)
+ MINBLKSIZE=512
+ MAXBLKSIZE=1048576
+ ;;
+ xnilfs2)
+ # nilfs2 supports blocksizes from 1024 to 4096
+ # but non-4096 results in kernel oops in some cases,
+ # avoid it.
+ MINBLKSIZE=4096
+ MAXBLKSIZE=4096
+ ;;
+ xsfs*)
+ MINBLKSIZE=512
+ MAXBLKSIZE=4096
+ ;;
+ xaffs | xaffs_intl)
+ MINBLKSIZE=512
+ MAXBLKSIZE=4096
+ ;;
+ xreiserfs*)
+ MINBLKSIZE=512
+ # OS LIMITATION: 8192 isn't supported.
+ MAXBLKSIZE=4096
+ ;;
+ x"mdraid"*)
+ MINBLKSIZE=4096
+ # OS LIMITATION: Linux oopses with >=32768K
+ MAXBLKSIZE=$((16384*1024))
+ ;;
+ x"lvm_raid1"* | x"lvm_raid4" | x"lvm_raid5" | x"lvm_raid6")
+ # OS LIMITATION: Linux crashes with less than 16384
+ MINBLKSIZE=16384
+ # Could go further but what's the point?
+ MAXBLKSIZE=$((65536*1024))
+ ;;
+ x"lvm_mirrorall")
+ MINBLKSIZE=2048
+ # Could go further but what's the point?
+ MAXBLKSIZE=$((65536*1024))
+ ;;
+ x"lvm_mirror1")
+ MINBLKSIZE=4096
+ # Could go further but what's the point?
+ MAXBLKSIZE=$((65536*1024))
+ ;;
+ x"lvm_stripe")
+ MINBLKSIZE=4096
+ # Could go further but what's the point?
+ MAXBLKSIZE=$((65536*1024))
+ ;;
+ x"lvm"*)
+ MINBLKSIZE=1024
+ # Could go further but what's the point?
+ MAXBLKSIZE=$((65536*1024))
+ ;;
+ xext4_encrypt)
+ # OS LIMITATION: Linux currently only allows the 'encrypt' feature
+ # in combination with block_size = PAGE_SIZE (4096 bytes on x86).
+ MINBLKSIZE=$(getconf PAGE_SIZE)
+ MAXBLKSIZE=$MINBLKSIZE
+ ;;
+ xext*)
+ MINBLKSIZE=1024
+ if [ $MINBLKSIZE -lt $SECSIZE ]; then
+ MINBLKSIZE=$SECSIZE
+ fi
+ MAXBLKSIZE=4096
+ ;;
+ xsquash*)
+ MINBLKSIZE=4096
+ MAXBLKSIZE=1048576;;
+ xxfs|xf2fs)
+ MINBLKSIZE=$SECSIZE
+ # OS Limitation: GNU/Linux doesn't accept > 4096
+ MAXBLKSIZE=4096;;
+ xxfs_crc)
+ # OS Limitation: GNU/Linux doesn't accept != 1024
+ MINBLKSIZE=1024
+ MAXBLKSIZE=1024;;
+ xudf)
+ MINBLKSIZE=1024
+ MAXBLKSIZE=4096;;
+ xbfs)
+ MINBLKSIZE=1024
+ MAXBLKSIZE=8192;;
+ xufs*)
+ MINBLKSIZE=4096
+ # OS Limitation: Linux rejects 65536 blocks.
+ MAXBLKSIZE=32768;;
+ xminix3)
+ # OS LIMITATION: Linux rejects non-power-of-two blocks.
+ # OS LIMITATION: Linux rejects > 4096.
+ MINBLKSIZE=1024
+ MAXBLKSIZE=4096;;
+ esac
+ if test "$BLKSTEP" -eq 0; then
+ blksizes="$(powrange "$MINBLKSIZE" "$MAXBLKSIZE")"
+ else
+ blksizes="$(range "$MINBLKSIZE" "$MAXBLKSIZE" "$BLKSTEP")"
+ fi
+ for BLKSIZE in $blksizes; do
+ MAXDEVICES=1
+ MINDEVICES=1
+ export fs
+ case x"$fs" in
+ x"zfs_raidz" | x"zfs_stripe" | x"zfs_mirror" | xbtrfs_raid0 \
+ | xbtrfs_raid1 | x"mdraid"*"_raid4" | x"mdraid"*"_raid5" \
+ | x"mdraid"*"_linear" \
+ | x"mdraid"*"_raid10" | xlvm_raid1* | xlvm_mirror1 | xlvm_mirrorall)
+ MINDEVICES=2
+ MAXDEVICES=7
+ ;;
+ xbtrfs_raid10)
+ MINDEVICES=4
+ MAXDEVICES=7
+ ;;
+ x"zfs_raidz2"| xlvm_raid5 | xlvm_raid4)
+ MINDEVICES=3
+ MAXDEVICES=7;;
+ x"zfs_raidz3" | x"mdraid"*"_raid6")
+ MINDEVICES=4
+ MAXDEVICES=7;;
+ xlvm_raid6)
+ MINDEVICES=5
+ MAXDEVICES=7;;
+ x"mdraid"*"_raid0" | x"mdraid"*"_raid1" | x"lvm" | xlvm_stripe)
+ MINDEVICES=1
+ MAXDEVICES=7;;
+ esac
+
+ for NDEVICES in $(range "$MINDEVICES" "$MAXDEVICES" 1); do
+ export NDEVICES
+ unset FSIMAGEP
+ FSIMAGEP="${tempdir}/${fs}_${SECSIZE}_${BLKSIZE}_${NDEVICES}_"
+ export FSIMAGEP
+ unset NEED_IMAGES;
+
+ case x$fs in
+ # RAID 1 has to work with even one device of the set.
+ xzfs_mirror | x"mdraid"*"_raid1" | xlvm_mirrorall | xlvm_raid1all)
+ NEED_IMAGES_N=1;;
+ # Degrade raidz by removing 3 devices
+ xzfs_raidz3)
+ NEED_IMAGES_N=$((NDEVICES-3));;
+ # Degrade raidz by removing 2 devices
+ xzfs_raidz2 | x"mdraid"*"_raid6" | x"lvm_raid6")
+ NEED_IMAGES_N=$((NDEVICES-2));;
+ # Degrade raidz and btrfs RAID1 by removing one device
+ xbtrfs_raid1 | xbtrfs_raid10 | xzfs_raidz | x"mdraid"*"_raid4" \
+ | x"mdraid"*"_raid5" | x"mdraid"*"_raid10" | xlvm_mirror1 \
+ | x"lvm_raid1" | x"lvm_raid4" | x"lvm_raid5")
+ NEED_IMAGES_N=$((NDEVICES-1));;
+ *)
+ NEED_IMAGES_N=$NDEVICES;;
+ esac
+ export NEED_IMAGES_N
+
+ MNTPOINTRO="${tempdir}/${fs}_ro"
+ MNTPOINTRW="${tempdir}/${fs}_rw"
+ MOUNTOPTS=""
+ MOUNTFS="$fs"
+ MASTER="${tempdir}/master"
+ FSLABEL="grub_;/testé莭莽茝😁киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewrewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfew"
+ CFILESRC=
+ for cand in /usr/share/dict/american-english /usr/share/dict/linux.words /data/data/com.termux/files/usr/share/hunspell/en_US.dic; do
+ if test -f "$cand" ; then
+ CFILESRC="$cand"
+ break
+ fi
+ done
+ if test "$CFILESRC" = "" ; then
+ echo "Couldn't find compressible file" >&2
+ exit 1
+ fi
+ case x"$fs" in
+ # FS LIMITATION: 8.3 names
+ xmsdos*)
+ CFILE="american.eng";;
+ xiso9660)
+ CFILE="american_english";;
+ *)
+ CFILE="american-english";;
+ esac
+ # OS LIMITATION: Limited by NAME_MAX (usually 255) in GNU/Linux
+ LONGNAME="qwertzuiopasdfghjklyxcvbnm1234567890qwertzuiopasdfghjklyxcvbnm1234567890oiewqfiewioqoiqoiurqruewqoiuwoieoiiuewqroreqiufieiuwrnureweriuvceoiroiewqoiricdsalkcndsakfirefoiwqeoircorejwoijfreoijojoiewjfwnfcoirenfoirefnreoifenoiwfnoi"
+ rm -rf "$MASTER"
+
+ case x"$fs" in
+ # FS LIMITATION: HFS+ label is at most 255 UTF-16 chars
+ # OS LIMITATION: Linux HFS+ tools check UTF-8 length and don't
+ # handle out-of-BMP characters
+ x"hfsplus" | x"hfsplus_casesens" | x"hfsplus_wrap")
+ FSLABEL="grub_;/testé䏌䐓䏕киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoiq"
+ ;;
+ # FS LIMITATION: btrfs label is at most 255 UTF-8 chars
+ x"btrfs"*)
+ FSLABEL="grub_;/testé莭莽😁киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoi";;
+
+ # FS LIMITATION: f2fs label is at most 512 UTF-16 chars
+ x"f2fs")
+ FSLABEL="grub_;/testé䏌䐓䏕киритiurewfceniuewruewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoirvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoircreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoiq";;
+
+ # FS LIMITATION: exfat is at most 15 UTF-16 chars
+ x"exfat")
+ FSLABEL="géт ;/莭莽😁кир";;
+ # FS LIMITATION: ntfs label is at most ?? UTF-16 chars
+ x"ntfs"*)
+ FSLABEL="grub_;/testéтi u莭😁茝кириrewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvniwnivrewiuvcrewvnuewvrrrewniureifiuewifjiww";;
+ # FS LIMITATION: nilfs2 label is at most 80 UTF-8 characters
+ x"nilfs2")
+ FSLABEL="grub_;/testéтi u😁莽茝кириrewfceniuewruevrewnuuireurevueurnievrewfne";;
+ # FS LIMITATION: afs and iso9660 label is at most 32 UTF-8 characters
+ x"afs" | xiso9660 | xrockridge | xrockridge_joliet\
+ | xiso9660_1999 | xrockridge_1999 | xrockridge_joliet_1999)
+ FSLABEL="gr_;/é莭莽😁кирит u";;
+ # FS LIMITATION: bfs label is at most 32 UTF-8 characters
+ # OS LIMITATION: bfs label can't contain ; or /
+ x"bfs")
+ FSLABEL="grub_é莭莽😁кирит u";;
+ # FS LIMITATION: Joliet label is at most 16 UTF-16 characters
+ # OS LIMITATION: xorriso doesn't handle out-of-BMP characters
+ xjoliet | xjoliet_1999)
+ FSLABEL="g;/_é䏌䐓䏕䎛䎾䏴кит u"
+ #FSLABEL="g;/_é莭莽😁кит u"
+ ;;
+ # FS LIMITATION: reiserfs, extN and jfs label is at most 16 UTF-8 characters
+ x"reiserfs_old" | x"reiserfs" | x"ext"* | x"lvm"* | x"mdraid"* | x"jfs" | x"jfs_caseins")
+ FSLABEL="g;/éт 莭😁";;
+ # FS LIMITATION: No underscore, space, semicolon, slash or international characters in UFS* in label. Limited to 32 UTF-8 characters
+ x"ufs1" | x"ufs1_sun" | x"ufs2")
+ FSLABEL="grubtest""ieurrucnenreeiurueurewf";;
+ # FS LIMITATION: XFS label is at most 12 UTF-8 characters
+ x"xfs"|x"xfs_crc")
+ FSLABEL="géт 😁к";;
+ # FS LIMITATION: FAT labels limited to 11 characters, no international characters or lowercase
+ x"vfat"* | xmsdos*)
+ FSLABEL="GRUBTEST ;_";;
+ # FS LIMITATION: AFFS is latin1. At most 29 characters
+ x"affs" | xaffs_intl)
+ FSLABEL="grub_tt? #*w;/e£@¡¤½¾{[]}<>.,";;
+ # FS LIMITATION: SFS is latin1. At most 30 characters
+ x"sfs"*)
+ FSLABEL="GRUB tt öäüé;/àèç åø¿ª©þð׫»µ¬";;
+ # FS LIMITATION: HFS is Mac-Roman. At most 27 characters
+ x"hfs")
+ FSLABEL="grub_t;/estéàèèéie fiucnree";;
+ # FS LIMITATION: UDF label is either up to 127 latin1 characters or 63 UTF-16 ones
+ # OS LIMITATION: Linux UDF tools force ASCII label ...
+ x"udf")
+ FSLABEL="grub_;/testurewfceniuewruevrewnuuireurevueurnievr";;
+ # FS LIMITATION: ZFS doesn't accept non-ASCII in label
+ # FIXME: since this is used as a path component for mount it's very limited in length
+ xzfs_* | xzfs)
+ FSLABEL="grub_testieufiue r";;
+ esac
+ case x"$fs" in
+ xmdraid*)
+ DISKSIZE=314572800;;
+ xlvm*)
+ LVMBLKMUL=$(((5800 * 1048576) / (8 * BLKSIZE * NDEVICES)))
+ DISKSIZE=$((8*BLKSIZE*LVMBLKMUL));;
+ # FS LIMITATION: some fs have disk size limit
+ x"vfat12" | xmsdos12)
+ DISKSIZE=$((4000*BLKSIZE));;
+ x"vfat12a" | xmsdos12a)
+ if [ $BLKSIZE -ge 2048 ]; then
+ DISKSIZE=$((2500*BLKSIZE))
+ else
+ DISKSIZE=$((3000*BLKSIZE))
+ fi
+ if [ $DISKSIZE -gt $((60000*SECSIZE)) ]; then
+ DISKSIZE=$((60000*SECSIZE))
+ fi;;
+ x"vfat16" | xmsdos16)
+ DISKSIZE=$((65000*BLKSIZE));;
+ x"vfat16a" | xmsdos16a)
+ DISKSIZE=$((60000*SECSIZE))
+ ;;
+ *)
+ DISKSIZE=10737418240;;
+ esac
+
+ if [ $DISKSIZE -ge $(((5800/NDEVICES)*1048576)) ]; then
+ DISKSIZE=$(((5800/NDEVICES)*1048576))
+ fi
+
+ case x"$fs" in
+ xvfat* | xmsdos* | xexfat* | xhfs | xhfsplus | xhfsplus_wrap | xaffs \
+ | xaffs_intl | xjfs_caseins | xsfs_caseins \
+ | xzfs_caseins | xiso9660)
+ CASESENS=n;;
+ *)
+ CASESENS=y;;
+ esac
+
+ BIGBLOCKCNT=$((5000 * 1048576))
+ case x"$fs" in
+ # FS LIMITATION: small filesystems
+ x"vfat12" | xmsdos12)
+ if [ $BLKSIZE -le 4096 ]; then
+ BIGBLOCKCNT=0
+ elif [ $BLKSIZE = 8192 ]; then
+ BIGBLOCKCNT=1500000
+ else
+ BIGBLOCKCNT=$((2000*BLKSIZE))
+ fi
+ ;;
+ x"vfat12a" | xmsdos12a)
+ if [ $BLKSIZE -le 4096 ] || [ $((128*SECSIZE)) = $BLKSIZE ]; then
+ BIGBLOCKCNT=0
+ else
+ BIGBLOCKCNT=700000
+ fi;;
+ x"vfat16a" | xmsdos16a)
+ if [ $((128*SECSIZE)) = $BLKSIZE ]; then
+ BIGBLOCKCNT=0
+ else
+ BIGBLOCKCNT=$((2500*SECSIZE))
+ fi
+ ;;
+ x"vfat16" | xmsdos16)
+ BIGBLOCKCNT=$((25000 * BLKSIZE))
+ if [ $BIGBLOCKCNT -gt 4294967295 ]; then
+ BIGBLOCKCNT=4294967295
+ fi
+ ;;
+ x"minix")
+ BIGBLOCKCNT=30000000;;
+
+ xexfat)
+ # Big blocks waste really a lot of space.
+ # Not much is left.
+ if [ $BLKSIZE = 2097152 ]; then
+ BIGBLOCKCNT=4500000000
+ fi
+ if [ $BLKSIZE = 4194304 ]; then
+ BIGBLOCKCNT=3500000000
+ fi
+ ;;
+ # FS LIMITATION: romfs image is limited to 4G.
+ x"romfs")
+ BIGBLOCKCNT=$((4000 * 1048576));;
+ # FS LIMITATION: These FS have uint32 as file size field
+ x"vfat"* | xmsdos* | x"cpio_crc" | x"cpio_newc" | x"cpio_bin" | x"cpio_hpbin" | xsfs*)
+ BIGBLOCKCNT=4294967295;;
+ # FS LIMITATION: These FS have int32 as file size field
+ # FIXME: not so sure about AFFS
+ # OS LIMITATION: minix2/minix3 could be formatted in a way to permit more.
+ x"minix3" | x"minix2" | x"hfs"| x"affs" | xaffs_intl | xreiserfs_old | xext2_old)
+ BIGBLOCKCNT=$((16#7fffffff));;
+
+ # FS LIMITATION: redundant storage
+ # We have only limited space. Mirroring multiplies it very effectively.
+ xmdraid* | xlvm* | xzfs_mirror | xbtrfs_raid1)
+ BIGBLOCKCNT=$((100 * 1048576));;
+ # We already test the FS for big files separately. Save some time here.
+ x"zfs_raid"* | x"zfs_stripe"* | x"zfs_mirror"* | x"btrfs_raid"*)
+ BIGBLOCKCNT=$((100 * 1048576));;
+
+ # OS LIMITATION: bfs_fuse bugs beyond that
+ xbfs)
+ BIGBLOCKCNT=$((800 * 1048576));;
+ esac
+
+ NOSYMLINK=n
+ case x"$fs" in
+ # FS LIMITATION: no symlinks on FAT, exFAT, HFS, plain ISO9660 and Joliet
+ # OS LIMITATION: ntfs-3g creates interix symlinks which aren't real symlinks
+ x"vfat"* | xmsdos* | x"hfs" | x"exfat" | x"ntfs"* \
+ | xiso9660 | xjoliet| xiso9660_1999 | xjoliet_1999)
+ NOSYMLINK=y;;
+ esac
+ NOHARDLINK=n
+ case x"$fs" in
+ # FS LIMITATION: no hardlinks on BFS, exfat, fat, hfs and SFS
+ xbfs | xexfat | x"vfat"* | xmsdos* | xhfs | xsfs | xsfs_caseins)
+ NOHARDLINK=y;;
+ # GRUB LIMITATION: no hardlink support on newc and hfs+
+ xcpio_crc | xcpio_newc | xhfsplus*)
+ NOHARDLINK=y;;
+ esac
+
+ # FS LIMITATION: some filesystems limit file name size
+ case x"$fs" in
+ x"cpio_ustar")
+ LONGNAME="`echo $LONGNAME |head -c 99`";;
+ x"hfs")
+ LONGNAME="`echo $LONGNAME |head -c 31`";;
+ x"minix" | x"minix2" | x"affs" | xaffs_intl | xiso9660)
+ LONGNAME="`echo $LONGNAME |head -c 30`";;
+ x"sfs"*)
+ LONGNAME="`echo $LONGNAME |head -c 105`";;
+ x"minix3")
+ LONGNAME="`echo $LONGNAME |head -c 60`";;
+ x"udf")
+ LONGNAME="`echo $LONGNAME |head -c 192`";;
+ # GRUB LIMITATION: GRUB prefers Joliet over ISO9660:1999
+ xjoliet | xjoliet_1999)
+ LONGNAME="`echo $LONGNAME |head -c 103`";;
+ xiso9660_1999)
+ LONGNAME="`echo $LONGNAME |head -c 207`";;
+ # FS LIMITATION: 8.3
+ xmsdos*)
+ LONGNAME="qwertzui.opa";;
+ esac
+ NOFILETIME=n
+ NOFSTIME=n
+ case x"$fs" in
+ # FIXME: Not sure about BtrFS, NTFS, JFS, AFS, UDF and SFS. Check it.
+ # FS LIMITATION: as far as I know those FS don't store their last modification date.
+ x"jfs_caseins" | x"jfs" | x"xfs" | x"xfs_crc" | x"btrfs"* | x"reiserfs_old" | x"reiserfs" \
+ | x"bfs" | x"afs" | x"f2fs" \
+ | x"tarfs" | x"cpio_"* | x"minix" | x"minix2" \
+ | x"minix3" | x"ntfs"* | x"udf" | x"sfs"*)
+ NOFSTIME=y;;
+ # OS LIMITATION: Linux doesn't update fstime.
+ # OS LIMITATION: Linux apparently uses localtime instead of UTC
+ xhfs)
+ NOFILETIME=y; NOFSTIME=y;;
+ # GRUB LIMITATION: FAT and exFAT use localtime. Unusable for GRUB
+ x"vfat"* | x"msdos"* | x"exfat")
+ NOFILETIME=y; NOFSTIME=y;;
+ # FS LIMITATION: romfs has no timestamps.
+ x"romfs")
+ NOFILETIME=y; NOFSTIME=y;;
+ esac
+
+ NOFSLABEL=n
+ case x"$fs" in
+ # FS LIMITATION: these filesystems have no label.
+ x"cpio_"* | x"tarfs" | x"squash4_"* | x"minix" | x"minix2" \
+ | x"minix3" | xreiserfs_old)
+ NOFSLABEL=y;;
+ esac
+
+ PDIRCOMPNUM=210
+ PDIR2COMPNUM=210
+
+ case x$fs in
+ # OS LIMITATION: bfs_fuse bugs beyond that
+ xbfs)
+ PDIRCOMPNUM=10
+ PDIR2COMPNUM=10;;
+ # OS LIMITATION: Linux supports only inline symlinks
+ xudf)
+ if [ $BLKSIZE = 1024 ]; then
+ PDIR2COMPNUM=113
+ fi ;;
+ # FS LIMITATION: at most 255 on path length
+ # FS LIMITATION: at most 100 on symlink length
+ xcpio_ustar)
+ PDIRCOMPNUM=84
+ PDIR2COMPNUM=30;;
+ # OS LIMITATION: Linux supports only symlink at most one block long on reiserfs
+ xreiserfs | xreiserfs_old)
+ if [ $BLKSIZE = 512 ]; then
+ PDIR2COMPNUM=114
+ fi ;;
+ # FS LIMITATION: SFS assumes that symlink
+ # with header fit in one block.
+ # FIXME: not sure about it.
+ xsfs | xsfs_caseins)
+ if [ $BLKSIZE = 512 ]; then
+ PDIR2COMPNUM=147
+ fi ;;
+ # FS LIMITATION: AFFS assumes that symlink
+ # with rather larger header fit in one block.
+ # FIXME: not sure about it.
+ xaffs | xaffs_intl)
+ if [ $BLKSIZE = 512 ]; then
+ PDIR2COMPNUM=97
+ fi ;;
+ esac
+
+
+ PDIR=""
+ # OS LIMITATION: Limited by PATH_MAX (usually 1024)
+ for i in $(range 0 $((PDIRCOMPNUM-1)) 1); do
+ PDIR="$PDIR/$i";
+ if test $((i%3)) = 0; then
+ PDIR="$PDIR/"
+ fi
+ done
+
+ PDIR2=""
+ # OS LIMITATION: Limited by PATH_MAX (usually 1024)
+ for i in $(range 0 $((PDIR2COMPNUM-1)) 1); do
+ PDIR2="${PDIR2}/$i";
+ if test $((i%3)) = 0; then
+ PDIR2="${PDIR2}/"
+ fi
+ done
+
+ PFIL="p.img"
+
+ unset LODEVICES
+ GENERATED=n
+ LODEVICES=
+ MOUNTDEVICE=
+
+ case x"$fs" in
+ x"tarfs" | x"cpio_"*| x"ziso9660" | x"romfs" | x"squash4_"*\
+ | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet \
+ | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 \
+ | xrockridge_joliet_1999)
+ MNTPOINTRW="$MASTER"
+ MNTPOINTRO="$MASTER"
+ GENERATED=y
+ mkdir -p "$MASTER";;
+ # No mkfs for GNU/Linux. Just unpack preformatted empty image
+ *)
+ mkdir -p "$MNTPOINTRW"
+ mkdir -p "$MNTPOINTRO"
+ for i in $(range 0 $((NDEVICES-1)) 1); do
+ dd if=/dev/zero of="$FSIMAGEP${i}.img" count=1 bs=1 seek=$((DISKSIZE-1)) &> /dev/null
+ LODEVICE=$(losetup --find --show "$FSIMAGEP${i}.img")
+ LODEVICES="$LODEVICES $LODEVICE"
+ if test "$i" = 0; then
+ MOUNTDEVICE="$LODEVICE"
+ fi
+ done ;;
+ esac
+
+ case x"$fs" in
+ x"afs")
+ ;;
+ x"btrfs")
+ "mkfs.btrfs" -s $SECSIZE -L "$FSLABEL" "${MOUNTDEVICE}" ;;
+ x"btrfs_zlib" | x"btrfs_lzo" | x"btrfs_zstd")
+ "mkfs.btrfs" -s $SECSIZE -L "$FSLABEL" "${MOUNTDEVICE}"
+ MOUNTOPTS="compress=${fs/btrfs_/},"
+ MOUNTFS="btrfs"
+ ;;
+ x"btrfs_raid0")
+ "mkfs.btrfs" -s $SECSIZE -d raid0 -m raid0 -L "$FSLABEL" $LODEVICES
+ MOUNTFS="btrfs"
+ ;;
+ x"btrfs_raid1")
+ "mkfs.btrfs" -s $SECSIZE -d raid1 -m raid1 -L "$FSLABEL" $LODEVICES
+ MOUNTFS="btrfs"
+ ;;
+ x"btrfs_raid10")
+ "mkfs.btrfs" -s $SECSIZE -d raid10 -m raid10 -L "$FSLABEL" $LODEVICES
+ MOUNTFS="btrfs"
+ ;;
+ x"btrfs_single")
+ "mkfs.btrfs" -s $SECSIZE -d single -L "$FSLABEL" $LODEVICES
+ MOUNTFS="btrfs"
+ ;;
+ x"exfat")
+ "mkfs.$fs" -s $((BLKSIZE/512)) -n "$FSLABEL" "${MOUNTDEVICE}"
+ MOUNTOPTS="iocharset=utf8,"
+ MOUNTFS="exfat-fuse";;
+ x"minix")
+ "mkfs.minix" "${MOUNTDEVICE}"
+ ;;
+ # mkfs.hfs and mkfs.hfsplus don't fill UUID.
+ x"hfsplus")
+ "mkfs.hfsplus" -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}"
+ dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#468)) conv=notrunc count=8 ;;
+ x"hfsplus_wrap")
+ "mkfs.hfsplus" -w -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}"
+ dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#468)) conv=notrunc count=8
+ MOUNTFS="hfsplus";;
+ x"hfsplus_casesens")
+ "mkfs.hfsplus" -s -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}"
+ dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#468)) conv=notrunc count=8
+ MOUNTFS="hfsplus";;
+ x"hfs")
+ "mkfs.hfs" -b $BLKSIZE -v "`echo $FSLABEL |recode utf8..macroman`" -h "${MOUNTDEVICE}"
+ dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#474)) conv=notrunc count=8
+ MOUNTOPTS="iocharset=utf8,codepage=macroman,"
+ ;;
+ x"vfat"*|xmsdos*)
+ BITS="${fs/vfat/}"
+ BITS="${BITS/msdos/}"
+ if [ "x${BITS:2:1}" = xa ]; then
+ A=-A
+ else
+ A=
+ fi
+ "mkfs.vfat" -a $A -S $SECSIZE -s $((BLKSIZE/SECSIZE)) -F "${BITS:0:2}" -n "$FSLABEL" "${MOUNTDEVICE}"
+ MOUNTOPTS="iocharset=utf8,codepage=437,"
+ MOUNTFS="$(echo "$fs"|sed 's,[0-9]*a\?$,,')";;
+ x"minix2")
+ "mkfs.minix" -v "${MOUNTDEVICE}"
+ MOUNTFS="minix";;
+ x"minix3")
+ "mkfs.minix" -B $BLKSIZE -3 "${MOUNTDEVICE}"
+ MOUNTFS="minix";;
+ x"ntfs"*)
+ "mkfs.ntfs" -s "$SECSIZE" -c "$BLKSIZE" -L "$FSLABEL" -Q -q "${MOUNTDEVICE}"
+ MOUNTOPTS="iocharset=utf8,compression,"
+ MOUNTFS="ntfs-3g";;
+ x"udf")
+ "mkudffs" --utf8 -b $BLKSIZE --lvid="$FSLABEL" "${MOUNTDEVICE}"
+ MOUNTOPTS="iocharset=utf8,bs=$BLKSIZE,";;
+ x"ufs2")
+ "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 2 "${MOUNTDEVICE}"
+ MOUNTOPTS="ufstype=ufs2,"
+ MOUNTFS="ufs";;
+ x"ufs1")
+ "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 1 "${MOUNTDEVICE}"
+ MOUNTOPTS="ufstype=44bsd,"
+ MOUNTFS="ufs";;
+ x"ufs1_sun")
+ "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 1 "${MOUNTDEVICE}"
+ MOUNTOPTS="ufstype=sun,"
+ MOUNTFS="ufs";;
+ x"zfs")
+ "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${MOUNTDEVICE}"
+ sleep 1
+ "zfs" create "$FSLABEL"/"grub fs"
+ sleep 1;;
+ x"zfs_caseins")
+ "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${MOUNTDEVICE}"
+ sleep 1
+ "zfs" create -o casesensitivity=insensitive "$FSLABEL"/"grub fs"
+ sleep 1;;
+ x"zfs_lzjb" | xzfs_gzip | xzfs_zle)
+ "zpool" create -O compression=${fs/zfs_/} -R "$MNTPOINTRW" "$FSLABEL" "${MOUNTDEVICE}"
+ sleep 1
+ "zfs" create -o compression=${fs/zfs_/} "$FSLABEL"/"grub fs"
+ sleep 1;;
+ x"zfs_raidz")
+ "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz1 $LODEVICES
+ sleep 1
+ "zfs" create "$FSLABEL"/"grub fs"
+ sleep 1;;
+ x"zfs_raidz2")
+ "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz2 $LODEVICES
+ sleep 1
+ "zfs" create "$FSLABEL"/"grub fs"
+ sleep 1;;
+ x"zfs_raidz3")
+ "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz3 $LODEVICES
+ sleep 1
+ "zfs" create "$FSLABEL"/"grub fs"
+ sleep 1;;
+ x"zfs_mirror")
+ "zpool" create -R "$MNTPOINTRW" "$FSLABEL" mirror $LODEVICES
+ sleep 1
+ "zfs" create "$FSLABEL"/"grub fs"
+ sleep 1;;
+ x"zfs_stripe")
+ "zpool" create -R "$MNTPOINTRW" "$FSLABEL" $LODEVICES
+ sleep 1
+ "zfs" create "$FSLABEL"/"grub fs"
+ sleep 1;;
+ x"tarfs" | x"cpio_"* | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 | xrockridge_joliet_1999 | x"ziso9660" | x"romfs" | x"squash4_"*)
+ INSTDEVICE=/dev/null;;
+ x"reiserfs")
+ "mkfs.reiserfs" --format=3.6 -b $BLKSIZE -l "$FSLABEL" -q "${MOUNTDEVICE}" ;;
+ x"reiserfs_old")
+ "mkfs.reiserfs" --format=3.5 -b $BLKSIZE -l "$FSLABEL" -q "${MOUNTDEVICE}"
+ MOUNTFS=reiserfs;;
+ x"jfs")
+ "mkfs.jfs" -L "$FSLABEL" -q "${MOUNTDEVICE}"
+ MOUNTOPTS="iocharset=utf8,";;
+ x"jfs_caseins")
+ "mkfs.jfs" -O -L "$FSLABEL" -q "${MOUNTDEVICE}"
+ MOUNTFS=jfs
+ MOUNTOPTS="iocharset=utf8,";;
+ x"mdraid"*)
+ mdadm -C --chunk=$((BLKSIZE/1024)) --force -e "${fs:6:1}.${fs:7:1}" "/dev/md/${fs}_${NDEVICES}" --level="${fs:13}" --raid-devices="$NDEVICES" $LODEVICES
+ MOUNTDEVICE="/dev/md/${fs}_${NDEVICES}"
+ MOUNTFS=ext2
+ "mkfs.ext2" -L "$FSLABEL" -q "${MOUNTDEVICE}" ;;
+ x"lvm"*)
+ for lodev in $LODEVICES; do
+ pvcreate "$lodev"
+ done
+ vgcreate -s $((BLKSIZE/1024))K grub_test $LODEVICES
+ if [ x$fs = xlvm ] ; then
+ lvcreate -l "$((NDEVICES*7*LVMBLKMUL))" -n testvol grub_test
+ elif [ x$fs = xlvm_stripe ] ; then
+ lvcreate -l "$((NDEVICES*7*LVMBLKMUL))" -i "$NDEVICES" -n testvol grub_test
+ elif [ x$fs = xlvm_mirror1 ] || [ x$fs = xlvm_raid1 ] ; then
+ lvcreate -m 1 -l "$((NDEVICES*2*LVMBLKMUL))" --type "${fs/lvm_/}" -n testvol grub_test
+ elif [ x$fs = xlvm_mirrorall ] ; then
+ lvcreate -m "$((NDEVICES-1))" -l "$((6*LVMBLKMUL))" --type mirror -n testvol grub_test
+ elif [ x$fs = xlvm_raid1all ] ; then
+ # Until version 2.02.103 LVM counts metadata segments
+ # twice when checking available space. Reduce segment
+ # count to work around it.
+ lvcreate -m "$((NDEVICES-1))" -l "$((6*LVMBLKMUL - 1))" --type raid1 -n testvol grub_test
+ elif [ x$fs = xlvm_raid4 ] || [ x$fs = xlvm_raid5 ]; then
+ lvcreate -l "$(((NDEVICES-1) * 5*LVMBLKMUL))" -i "$((NDEVICES-1))" --type "${fs/lvm_/}" -n testvol grub_test
+ elif [ x$fs = xlvm_raid6 ]; then
+ lvcreate -l "$(((NDEVICES-2) * 5*LVMBLKMUL))" -i "$((NDEVICES-2))" --type "${fs/lvm_/}" -n testvol grub_test
+ fi
+ MOUNTDEVICE="/dev/mapper/grub_test-testvol"
+ MOUNTFS=ext2
+ "mkfs.ext2" -L "$FSLABEL" -q "${MOUNTDEVICE}" ;;
+ xf2fs)
+ "mkfs.f2fs" -l "$FSLABEL" -q "${MOUNTDEVICE}" ;;
+ xnilfs2)
+ "mkfs.nilfs2" -L "$FSLABEL" -b $BLKSIZE -q "${MOUNTDEVICE}" ;;
+ xext2_old)
+ MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext2" -r 0 -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}"
+ MOUNTFS=ext2
+ ;;
+ xext4_metabg)
+ MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext4" -O meta_bg,^resize_inode -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}"
+ MOUNTFS=ext4
+ ;;
+ xext4_encrypt)
+ MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext4" -O encrypt -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}"
+ MOUNTFS=ext4
+ ;;
+ xext*)
+ MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.$fs" -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" ;;
+ xxfs)
+ "mkfs.xfs" -m crc=0 -b size=$BLKSIZE -s size=$SECSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" ;;
+ xxfs_crc)
+ MOUNTFS="xfs"
+ "mkfs.xfs" -m crc=1 -b size=$BLKSIZE -s size=$SECSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" ;;
+ *)
+ echo "Add appropriate mkfs command here"
+ exit 1
+ ;;
+ esac
+ BASEFILE="1.img"
+ NASTYFILE=".?*\\!\"#%@\$%&'()+ ,-.:;<=>^{_}[]\`|~."
+ case x"$fs" in
+
+ # FS LIMITATION: AFFS and SFS don't accept :
+ xsfs*)
+ NASTYFILE=".?*\\!\"#%@\$%&'()+ ,-.;<=>^{_}[]\`|~.";;
+ # FS LIMITATION: AFFS is limited in file name length (30)
+ x"affs" | xaffs_intl)
+ NASTYFILE=".?*\\!\"#@\$'()+ ,-;<=>^{_}[]\`|~.";;
+ # FS LIMITATION: hfs, minix and minix2 are limited in file name length (30 or 31)
+ x"hfs" | x"minix" | x"minix2")
+ NASTYFILE=".?*\\!\"#@\$&'()+ ,-:;<=>{}[]\`|~.";;
+ # FS LIMITATION: FAT doesn't accept ?, *, \, ", :, <, >, |
+ # FS LIMITATION: FAT discards dots at the end.
+ x"vfat"* | x"exfat")
+ NASTYFILE=".!#%@\$%&'()+ ,-.;=^{_}[]\`~";;
+ # FS LIMITATION: 8.3 limitations apply
+ x"msdos"*)
+ NASTYFILE="!#%@\$%&.;=^";;
+ # FS LIMITATION: No ' ', '*', '/', ':', ';', '?', '\\' in joliet
+ # GRUB LIMITATION: GRUB prefers Joliet over ISO9660:1999
+ xjoliet | xjoliet_1999)
+ NASTYFILE=".!\"#%@\$%&'()+,-.<=>^{_}[]\`|~.";;
+ # FS LIMITATION: iso9660 accepts only [0-9A-Z_]*, 32 characters at most
+ xiso9660)
+ NASTYFILE="0123456789_acefghijknopqrvwxyz";;
+ esac
+
+ case x"$fs" in
+ # FS LIMITATION: HFS, AFFS and SFS use legacy codepage (mac-roman or latin1)
+ x"sfs"* | x"hfs" | x"affs" | xaffs_intl)
+ IFILE="éàèüöäëñ"
+ ISYM="ëñéüöäàè"
+ ;;
+ # FS LIMITATION: filename length limitation.
+ x"minix" | x"minix2")
+ IFILE="éàèüö😁ñкиΕλκά"
+ ISYM="Ελκάкиéà😁öäëñ"
+ ;;
+ xminix3)
+ IFILE="éàèüöäëñкирица莭茝Ελλικά😁😜😒"
+ ISYM="Ελλικά😁😜😒莭茝кирицаéàèüöäëñ";;
+ # GRUB LIMITATION: HFS+ uses NFD. GRUB doesn't handle NF conversion.
+ # OS LIMITATION: Linux doesn't handle out-of-BMP characters for UTF-16
+ x"hfsplus" | x"hfsplus_casesens" | x"hfsplus_wrap")
+ IFILE="éàèüöäëñкирилица䏌䐓䏕Ελληνικα̍䏌䐓䏕"
+ ISYM="Ελληνικα̍кирилица䏌䐓䏕éàèüöäëñ䏌䐓䏕"
+ ;;
+ # GRUB LIMITATION: On case-insensitive ZFS isn't supported with non-uppercase characters
+ xzfs_caseins)
+ IFILE="ÉÀÈÜÖÄËÑКИРИЛИЦА莭莽茝ΕΛΛΗΝΙΚΆ😁😜😒"
+ ISYM="ΕΛΛΗΝΙΚΆКИРИЛИЦА😁😜😒ÉÀÈÜÖÄËÑ莭莽茝";;
+ # FS LIMITATION: 8.3 CP437
+ x"msdos"*)
+ IFILE="éàèüöäëñ.éàè"
+ ;;
+ # FS LIMITATION: iso9660 is ASCII-only.
+ x"iso9660")
+ IFILE="abcdefghijkmmnop"
+ ;;
+ # OS LIMITATION: Linux doesn't handle out-of-BMP characters for UTF-16
+ # OS LIMITATION: xorriso doesn't handle out-of-BMP characters
+ xjoliet | xjoliet_1999 | x"vfat"* | x"jfs"* | x"udf"*)
+ IFILE="éàèüöäëñкирилица䏌䐓䏕Ελληνικά䏌䐓䏕"
+ ISYM="Ελληνικάкирилица䏌䐓䏕éàèüöäëñ䏌䐓䏕";;
+ *)
+ IFILE="éàèüöäëñкирилица莭莽茝Ελληνικά😁😜😒"
+ ISYM="Ελληνικάкирилица😁😜😒éàèüöäëñ莭莽茝";;
+ esac
+ BIGFILE="big.img"
+ BASESYM="sym"
+ BASEHARD="hard"
+ SSYM="///sdir////ssym"
+ USYM="///sdir////usym"
+ LONGSYM="longsym"
+ PSYM="psym"
+ OSDIR=""
+ GRUBDEVICE=loop0
+ case x"$fs" in
+ xmdraid*)
+ GRUBDEVICE="mduuid/`mdadm --detail --export $MOUNTDEVICE | grep MD_UUID=|sed 's,MD_UUID=,,g;s,:,,g'`";;
+ xlvm*)
+ GRUBDEVICE="lvm/grub_test-testvol";;
+ esac
+ GRUBDIR="($GRUBDEVICE)"
+ case x"$fs" in
+ x"zfs"*)
+ OSDIR="grub fs/"
+ GRUBDIR="($GRUBDEVICE)/grub fs@";;
+ x"tarfs" | x"cpio_"* | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 | xrockridge_joliet_1999 | x"ziso9660" | x"romfs" | x"squash4_"* | xafs)
+ ;;
+ *)
+ if ! mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRW" -o ${MOUNTOPTS}${SELINUXOPTS}rw ; then
+ echo "MOUNT FAILED."
+ for lodev in $LODEVICES; do
+ while ! losetup -d "$lodev"; do
+ sleep 1
+ done
+ done
+ for i in $(range 0 $((NDEVICES-1)) 1); do
+ rm "$FSIMAGEP${i}.img"
+ done
+ exit 1;
+ fi
+ ;;
+ esac
+ case x"$fs" in
+ # FS LIMITATION: redundant storage
+ xmdraid* | xlvm*)
+ BLOCKCNT=1048576;;
+ x"zfs_raid"* | x"zfs_stripe"* | x"zfs_mirror"* | x"btrfs_raid"*)
+ BLOCKCNT=1048576;;
+
+ # FS LIMITATION: small filesystems
+ x"vfat16a" | x"msdos16a")
+ BLOCKCNT=65536;;
+ x"vfat12a" | xmsdos12a)
+ BLOCKCNT=32768;;
+ xminix)
+ BLOCKCNT=2621440;;
+ xvfat16 | xmsdos16)
+ if [ $BLKSIZE = 512 ] || [ $BLKSIZE = 1024 ]; then
+ BLOCKCNT=1048576
+ else
+ BLOCKCNT=5242880
+ fi
+ ;;
+ xvfat12 | xmsdos12)
+ BLOCKCNT=$((100*BLKSIZE))
+ if [ $BLOCKCNT -gt 5242880 ]; then
+ BLOCKCNT=5242880;
+ fi
+ ;;
+ *)
+ BLOCKCNT=5242880;;
+ esac
+ # Make sure file is not exact multiple of block size. This helps to force
+ # tail packing in case of squash4.
+ BLOCKCNT="$((BLOCKCNT-1))"
+ case x"$fs" in
+ x"ntfscomp")
+ setfattr -h -v 0x00000800 -n system.ntfs_attrib_be "$MNTPOINTRW/$OSDIR";;
+ esac
+ # OS LIMITATION: No AFS support under GNU/Linux
+ mkdir "$MNTPOINTRW/$OSDIR/sdir"
+ mkdir -p "$MNTPOINTRW/$OSDIR/$PDIR"
+ "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/sdir/2.img"
+ "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$BASEFILE"
+ "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$NASTYFILE"
+ "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$IFILE"
+ "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$LONGNAME"
+ "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$PDIR/$PFIL"
+ if [ $PDIR != $PDIR2 ]; then
+ "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/${PDIR2}/$PFIL"
+ fi
+ "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/CaSe"
+ if [ x$CASESENS = xy ]; then
+ "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/cAsE"
+ fi
+ if (test x$fs = xvfat12a || test x$fs = xmsdos12a) && test x$BLKSIZE = x131072; then
+ # With this config there isn't enough space for full copy.
+ # Copy as much as we can
+ cp "${CFILESRC}" "$MNTPOINTRW/$OSDIR/${CFILE}" &> /dev/null;
+ else
+
+ cp "${CFILESRC}" "$MNTPOINTRW/$OSDIR/${CFILE}";
+
+ fi
+
+ if [ x$NOSYMLINK != xy ]; then
+ ln -s "$BASEFILE" "$MNTPOINTRW/$OSDIR/$BASESYM"
+ ln -s "2.img" "$MNTPOINTRW/$OSDIR/$SSYM"
+ ln -s "../1.img" "$MNTPOINTRW/$OSDIR/$USYM"
+ ln -s "$LONGNAME" "$MNTPOINTRW/$OSDIR/$LONGSYM"
+ ln -s "${PDIR2}/$PFIL" "$MNTPOINTRW/$OSDIR/$PSYM"
+ ln -s "$IFILE" "$MNTPOINTRW/$OSDIR/$ISYM"
+ fi
+ if [ x$NOHARDLINK != xy ]; then
+ ln "$MNTPOINTRW/$OSDIR/$BASEFILE" "$MNTPOINTRW/$OSDIR/$BASEHARD"
+ fi
+
+ case x"$fs" in
+ x"afs")
+ ;;
+ x"zfs"*)
+ while ! zpool export "$FSLABEL" ; do
+ sleep 1;
+ done
+ sleep 2
+ ;;
+ x"tarfs")
+ (cd "$MASTER"; tar cf "${FSIMAGEP}0.img" .) ;;
+ x"cpio_"*)
+ (cd "$MASTER"; find . | cpio -o -H "$(echo ${fs} | sed 's@^cpio_@@')" > "${FSIMAGEP}0.img" ) ;;
+ x"ziso9660")
+ FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
+ xorriso -compliance rec_mtime -set_filter_r --zisofs -- -zisofs default -as mkisofs -iso-level 3 -graft-points -R -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" -- -set_filter_r --zisofs -- -zisofs default -add /="$MASTER" ;;
+ x"iso9660")
+ FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
+ xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;;
+ x"joliet")
+ FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
+ xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;;
+ x"rockridge")
+ FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
+ xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;;
+ x"rockridge_joliet")
+ FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
+ xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;;
+ x"iso9660_1999")
+ FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
+ xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;;
+ x"joliet_1999")
+ FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
+ xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;;
+ x"rockridge_1999")
+ FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
+ xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;;
+ x"rockridge_joliet_1999")
+ FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
+ xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;;
+ x"romfs")
+ genromfs -V "$FSLABEL" -f "${FSIMAGEP}0.img" -d "$MASTER" ;;
+ xsquash4_*)
+ echo mksquashfs "$MASTER" "${FSIMAGEP}0.img" -always-use-fragments -comp "${fs/squash4_/}" -b $BLKSIZE
+ mksquashfs "$MASTER" "${FSIMAGEP}0.img" -always-use-fragments -comp "${fs/squash4_/}" -b $BLKSIZE ;;
+ x"bfs")
+ sleep 1
+ fusermount -u "$MNTPOINTRW"
+ ;;
+ xlvm*)
+ sleep 1
+ for try in $(range 0 20 1); do
+ if umount "$MNTPOINTRW" ; then
+ break;
+ fi
+ sleep 1;
+ done
+ UMOUNT_TIME=$(date -u "+%Y-%m-%d %H:%M:%S")
+ sleep 1
+ vgchange -a n grub_test
+ ;;
+ xmdraid*)
+ sleep 1
+ for try in $(range 0 20 1); do
+ if umount "$MNTPOINTRW" ; then
+ break;
+ fi
+ sleep 1;
+ done
+ UMOUNT_TIME=$(date -u "+%Y-%m-%d %H:%M:%S")
+ sleep 1
+ mdadm --stop /dev/md/"${fs}_$NDEVICES"
+ ;;
+ *)
+ sleep 1
+ for try in $(range 0 20 1); do
+ if umount "$MNTPOINTRW" ; then
+ break;
+ fi
+ sleep 1;
+ done
+ ;;
+ esac
+ sleep 1
+
+ case x"$fs" in
+ x"zfs"*)
+ "zpool" import -d /dev -R "$MNTPOINTRO" "$FSLABEL"
+ ;;
+ x"tarfs")
+ ;;
+ x"cpio_"*)
+ ;;
+ x"ziso9660")
+ ;;
+ xiso9660 | xrockridge | xjoliet | xrockridge_joliet)
+ ;;
+ xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999)
+ ;;
+ x"romfs")
+ ;;
+ xsquash4_*)
+ ;;
+ xlvm*)
+ vgchange -a y grub_test
+ sleep 1
+ mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;;
+ xmdraid*)
+ mdadm --assemble /dev/md/"${fs}_$NDEVICES" $LODEVICES
+ sleep 1
+ mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;;
+ *)
+ mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;;
+ esac
+
+ run_grubfstest ls -- -la
+ case x"$fs" in
+ x"zfs"*)
+ LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/grub fs@/");;
+ *)
+ LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/");;
+ esac
+ if echo "$LSROUT" | grep -F " $BASEFILE" | grep "$BLOCKCNT" > /dev/null; then
+ :
+ else
+ echo LIST FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO"
+ exit 1
+ fi
+
+ if echo "$LSROUT" | grep -F " $NASTYFILE" | grep "$BLOCKCNT"> /dev/null; then
+ :
+ else
+ echo NLIST FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -lA "$MNTPOINTRO"
+ exit 1
+ fi
+
+ if echo "$LSROUT" | grep -F " $IFILE" | grep "$BLOCKCNT"> /dev/null; then
+ :
+ else
+ echo ILIST FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO"
+ exit 1
+ fi
+
+ if echo "$LSROUT" | grep -F " $LONGNAME" | grep "$BLOCKCNT"> /dev/null; then
+ :
+ else
+ echo LONG LIST FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO"
+ exit 1
+ fi
+
+ if [ x$NOFILETIME != xy ]; then
+ filtime=$(TZ=UTC ls --time-style=+%Y%m%d%H%M%S -l -d "$MNTPOINTRO/$OSDIR/$BASEFILE"|awk '{print $6; }')
+ if echo "$LSROUT" | grep -F "$filtime $BASEFILE" > /dev/null; then
+ :
+ else
+ echo TIME FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO"
+ exit 1
+ fi
+
+ filtime=$(TZ=UTC ls --time-style=+%Y%m%d%H%M%S -l -d "$MNTPOINTRO/$OSDIR/$LONGNAME"|awk '{print $6; }')
+ if echo "$LSROUT" | grep -F "$filtime $LONGNAME" > /dev/null; then
+ :
+ else
+ echo LONG TIME FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO"
+ exit 1
+ fi
+ fi
+
+ case x"$fs" in
+ x"zfs"*)
+ LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/grub fs@/.");;
+ *)
+ LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/.");;
+ esac
+ if echo "$LSROUT" | grep -F " $BASEFILE" | grep "$BLOCKCNT" > /dev/null; then
+ :
+ else
+ echo DOT IN ROOTDIR FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO"
+ exit 1
+ fi
+
+ case x"$fs" in
+ x"zfs"*)
+ ;;
+ *)
+ LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/..");
+ if echo "$LSROUT" | grep -F " $BASEFILE" | grep "$BLOCKCNT" > /dev/null; then
+ :
+ else
+ echo DOTDOT IN ROOTDIR FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO"
+ exit 1
+ fi
+ ;;
+ esac
+
+ case x"$fs" in
+ x"zfs"*)
+ LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/////sdir");;
+ *)
+ LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/////sdir");;
+ esac
+ if echo "$LSROUT" | grep -F " 2.img" | grep $BLOCKCNT > /dev/null; then
+ :
+ else
+ echo SLIST FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO/sdir"
+ exit 1
+ fi
+
+ case x"$fs" in
+ x"zfs"*)
+ LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/$PDIR");;
+ *)
+ LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/$PDIR");;
+ esac
+ if echo "$LSROUT" | grep -F " p.img" | grep $BLOCKCNT > /dev/null; then
+ :
+ else
+ echo PLIST FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO/$PDIR"
+ exit 1
+ fi
+
+ case x"$fs" in
+ x"zfs"*)
+ LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/sdir/.");;
+ *)
+ LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/sdir/.");;
+ esac
+ if echo "$LSROUT" | grep -F " 2.img" | grep $BLOCKCNT > /dev/null; then
+ :
+ else
+ echo DOT IN SUBDIR FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO/$OSDIR/sdir"
+ exit 1
+ fi
+
+ case x"$fs" in
+ x"zfs"*)
+ LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/sdir/../sdir");;
+ *)
+ LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/sdir/../sdir");;
+ esac
+ if echo "$LSROUT" | grep -F " 2.img" | grep $BLOCKCNT > /dev/null; then
+ :
+ else
+ echo DOTDOT IN SUBDIR FAIL
+ echo "$LSROUT"
+ TZ=UTC ls -l "$MNTPOINTRO/$OSDIR/ssdir"
+ exit 1
+ fi
+
+ LSOUT=`run_grubfstest ls -- -l "($GRUBDEVICE)"`
+ if [ x"$NOFSLABEL" = xy ]; then
+ :
+ elif echo "$LSOUT" | grep -F "Label \`$FSLABEL'" > /dev/null; then
+ :
+ else
+ echo LABEL FAIL
+ echo "$LSOUT"
+ blkid "${MOUNTDEVICE}"
+ exit 1
+ fi
+
+ # Inconsistencies between GRUB and blkid.
+ case x"$fs" in
+ x"iso9660" | x"ziso9660" | xrockridge | xjoliet | xrockridge_joliet | x"iso9660_1999" | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) ;;
+ x"zfs"*)
+ for lodev in $LODEVICES; do
+ FSUUID=$(printf "%016x\n" $(blkid -o export "$lodev" |grep -F UUID=|sed s,UUID=,,g))
+ if [ "$FSUUID" != 0000000000000000 ]; then
+ break;
+ fi
+ done;;
+ *)
+ FSUUID=`blkid -o export "${MOUNTDEVICE}" |grep -F UUID=|sed s,UUID=,,g`
+ ;;
+ esac
+ case x"$fs" in
+ x"hfs"*)
+ GRUBUUID="`run_grubfstest xnu_uuid "$GRUBDEVICE"`"
+ if [ x"$GRUBUUID" = x"$FSUUID" ]; then
+ :
+ else
+ echo UUID FAIL
+ echo "$LSOUT"
+ echo "$GRUBUUID"
+ for lodev in $LODEVICES; do
+ blkid "$lodev"
+ done
+ exit 1
+ fi
+ ;;
+ # FS LIMITATION: romfs, cpio, tar, squash4, minix, AFS, old reiserfs and minix2
+ # have no UUID.
+ # GRUB LIMITATION: use creation date for squash4, AFFS and SFS?
+ # GRUB LIMITATION: use tags serials on UDF?
+ # GRUB LIMITATION: use root ctime on cpio, tar, minix*, UDF, reiserfs_old?
+ # GRUB LIMITATION: Support Atari UUIDs
+ x"romfs" | x"cpio_"* | x"tarfs" | x"squash4_"* | x"minix" \
+ | x"minix2" | x"minix3" | x"affs" | xaffs_intl \
+ | x"udf" | xvfat12a | xvfat16a | xmsdos12a | xmsdos16a | xafs | xsfs* \
+ | xreiserfs_old)
+ ;;
+ *)
+ if [ x"$FSUUID" = x ]; then
+ echo "Warning: blkid couldn't retrieve UUID"
+ elif echo "$LSOUT" | grep -F 'UUID '"$FSUUID"' ' > /dev/null; then
+ :
+ else
+ echo UUID FAIL
+ echo "$FSUUID"
+ echo "$LSOUT"
+ blkid "${MOUNTDEVICE}"
+ exit 1
+ fi
+ ;;
+ esac
+
+ if [ x$NOFSTIME != xy ]; then
+ case x$fs in
+ xiso9660 | xziso9660 | xrockridge | xjoliet | xrockridge_joliet | xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999)
+ FSTIME="$(date -d "$(echo ${FSUUID} | awk -F - '{ print $1"-"$2"-"$3" "$4":"$5":"$6 ;}')" '+%Y-%m-%d %H:%M:%S')";;
+ xlvm*|xmdraid*)
+ # With some abstractions like mdraid flushing to disk
+ # may be delayed for a long time.
+ FSTIME="$UMOUNT_TIME";;
+ *)
+ FSTIME="$(TZ=UTC ls --time-style="+%Y-%m-%d_%H:%M:%S" -l -d "${FSIMAGEP}0.img"|awk '{print $6; }'|sed 's,_, ,g')";;
+ esac
+ # With some abstractions like mdraid computing of UMOUNT_TIME
+ # is not precise. Account for small difference here.
+ FSTIMEM1="$(date -d "$FSTIME UTC -1 second" -u "+%Y-%m-%d %H:%M:%S")"
+ FSTIMEM2="$(date -d "$FSTIME UTC -2 second" -u "+%Y-%m-%d %H:%M:%S")"
+ FSTIMEM3="$(date -d "$FSTIME UTC -3 second" -u "+%Y-%m-%d %H:%M:%S")"
+
+ if echo "$LSOUT" | grep -F 'Last modification time '"$FSTIME" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM1" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM2" || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM3" > /dev/null; then
+ :
+ else
+ echo FSTIME FAIL
+ echo "$FSTIME"
+ echo "$LSOUT"
+ exit 1
+ fi
+ fi
+
+ if [ x$NOHARDLINK != xy ]; then
+ if run_grubfstest cmp "$GRUBDIR/$BASEHARD" "$MNTPOINTRO/$OSDIR/$BASEFILE" ; then
+ :
+ else
+ echo HARDLINK FAIL
+ exit 1
+ fi
+ fi
+
+ if [ x$NOSYMLINK != xy ]; then
+ if run_grubfstest cmp "$GRUBDIR/$BASESYM" "$MNTPOINTRO/$OSDIR/$BASEFILE" ; then
+ :
+ else
+ echo SYMLINK FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/$LONGSYM" "$MNTPOINTRO/$OSDIR/$LONGNAME" ; then
+ :
+ else
+ echo LONG SYMLINK FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/$ISYM" "$MNTPOINTRO/$OSDIR/$IFILE" ; then
+ :
+ else
+ echo INTL SYMLINK FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/$SSYM" "$MNTPOINTRO/$OSDIR/////sdir/////2.img" ; then
+ :
+ else
+ echo SDIR SYMLINK FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/$USYM" "$MNTPOINTRO/$OSDIR/1.img" ; then
+ :
+ else
+ echo SDIR SYMLINK FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/$PSYM" "$MNTPOINTRO/$OSDIR/${PDIR2}/$PFIL" ; then
+ :
+ else
+ echo PATH LONG SYMLINK FAIL
+ exit 1
+ fi
+ fi
+
+ if run_grubfstest cmp "$GRUBDIR/$BASEFILE" "$MNTPOINTRO/$OSDIR/$BASEFILE" ; then
+ :
+ else
+ echo READ FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/$NASTYFILE" "$MNTPOINTRO/$OSDIR/$NASTYFILE" ; then
+ :
+ else
+ echo NREAD FAIL
+ exit 1
+ fi
+ # Reference archive contains original name
+ if run_grubfstest cmp "$GRUBDIR/$LONGNAME" "$MNTPOINTRO/$OSDIR/$LONGNAME" ; then
+ :
+ else
+ echo LONG NAME READ FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/////sdir/////2.img" "$MNTPOINTRO/$OSDIR/sdir/2.img" ; then
+ :
+ else
+ echo LONG NAME READ FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/$IFILE" "$MNTPOINTRO/$OSDIR/$IFILE" ; then
+ :
+ else
+ echo IREAD FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/$PDIR/$PFIL" "$MNTPOINTRO/$OSDIR/$PDIR/$PFIL" ; then
+ :
+ else
+ echo PREAD FAIL
+ echo cmp "$GRUBDIR/$PDIR/$PFIL" "$MNTPOINTRO/$OSDIR/$PDIR/$PFIL"
+ exit 1
+ fi
+ ok=true
+ if ! run_grubfstest cmp "$GRUBDIR/${CFILE}" "$MNTPOINTRO/$OSDIR/${CFILE}" ; then
+ ok=false;
+ fi
+ if test x$ok = xtrue; then
+ :
+ else
+ echo CREAD FAIL
+ exit 1
+ fi
+
+ if [ x$CASESENS = xy ]; then
+ if run_grubfstest cmp "$GRUBDIR/CaSe" "$MNTPOINTRO/$OSDIR/CaSe" ; then
+ :
+ else
+ echo CASE1 READ FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/cAsE" "$MNTPOINTRO/$OSDIR/cAsE" ; then
+ :
+ else
+ exit 1
+ fi
+ if cmp "$MNTPOINTRO/$OSDIR/cAsE" "$MNTPOINTRO/$OSDIR/CaSe" > /dev/null ; then
+ exit 1
+ fi
+ if test x$ok = xtrue; then
+ :
+ else
+ echo CASE READ FAIL
+ exit 1
+ fi
+ else
+ # OS LIMITATION: Linux make FAT (partially) case-sensitive...
+ # ISO9660 is generated and master doesn't change
+ case x$fs in
+ xiso9660 | xvfat*)
+ CASEX=CaSe;;
+ *)
+ CASEX=cAsE;;
+ esac
+ if run_grubfstest cmp "$GRUBDIR/CaSe" "$MNTPOINTRO/$OSDIR/${CASEX}" ; then
+ :
+ else
+ echo CASE1 READ FAIL
+ exit 1
+ fi
+ if run_grubfstest cmp "$GRUBDIR/cAsE" "$MNTPOINTRO/$OSDIR/CaSe" ; then
+ :
+ else
+ echo CASE2 READ FAIL
+ exit 1
+ fi
+ if ! cmp "$MNTPOINTRO/$OSDIR/CaSe" "$MNTPOINTRO/$OSDIR/${CASEX}" > /dev/null ; then
+ echo CASE CMP READ FAIL
+ exit 1
+ fi
+ if test x$ok = xtrue; then
+ :
+ else
+ echo CASE READ FAIL
+ exit 1
+ fi
+ fi
+
+ case x"$fs" in
+ x"zfs"*)
+ while ! zpool export "$FSLABEL" ; do
+ sleep 1;
+ done
+ sleep 5;;
+ x"tarfs" | x"cpio_"* | xrockridge | xjoliet | xrockridge_joliet | x"ziso9660" | x"romfs" | x"squash4_"* | xiso9660 | xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999)
+ rm -rf "$MNTPOINTRW";;
+ x"afs")
+ rm -rf "$MNTPOINTRO"
+ ;;
+ *)
+ sleep 1
+ umount "$MNTPOINTRO" || true
+ umount "$MNTPOINTRW" || true
+ esac
+ sleep 1
+ case x"$fs" in
+ xmdraid*)
+ mdadm --stop /dev/md/"${fs}_$NDEVICES"
+ sleep 1
+ ;;
+ xlvm*)
+ vgchange -a n grub_test
+ sleep 1
+ ;;
+ esac
+ case x"$fs" in
+ x"tarfs" | x"cpio_"* | x"iso9660" | xrockridge | xjoliet | xrockridge_joliet | x"ziso9660" | x"romfs" | x"squash4_"* | x"iso9660_1999" | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) ;;
+ *)
+ for lodev in $LODEVICES; do
+ while ! losetup -d "$lodev"; do
+ sleep 1
+ done
+ done;;
+ esac
+ for i in $(range 0 $((NDEVICES-1)) 1); do
+ rm "$FSIMAGEP${i}.img"
+ done
+ if [ x"$fs" = x"zfs" ]; then
+ rmdir "$MNTPOINTRW"/"grub fs" || true
+ rmdir "$MNTPOINTRO"/"grub fs" || true
+ fi
+ rm -rf "$MNTPOINTRW" || true
+ rm -rf "$MNTPOINTRO" || true
+ done
+ done
+done
+rmdir "${tempdir}"
diff --git a/tests/util/grub-shell-tester.in b/tests/util/grub-shell-tester.in
new file mode 100644
index 0000000..8a87109
--- /dev/null
+++ b/tests/util/grub-shell-tester.in
@@ -0,0 +1,106 @@
+#! @BUILD_SHEBANG@
+set -e
+
+# Compares GRUB script output with BASH output.
+# Copyright (C) 2009,2010 Free Software Foundation, Inc.
+#
+# GRUB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+
+# Initialize some variables.
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+datarootdir="@datarootdir@"
+builddir="@builddir@"
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+
+# Force build directory components
+PATH="${builddir}:$PATH"
+export PATH
+
+# Usage: usage
+# Print the usage.
+usage () {
+ cat <<EOF
+Usage: $0 [OPTION] [SOURCE]
+Compares GRUB script output with BASH shell output.
+
+ -h, --help print this message and exit
+ -v, --version print the version information and exit
+ --modules=MODULES pre-load specified modules MODULES
+ --qemu-opts=OPTIONS extra options to pass to Qemu instance
+
+$0 compares GRUB script output with BASH shell output and prints their
+differences.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+ case "$option" in
+ -h | --help)
+ usage
+ exit 0 ;;
+ -v | --version)
+ echo "$0 (GNU GRUB ${PACKAGE_VERSION})"
+ exit 0 ;;
+ --modules=*)
+ ms=`echo "$option" | sed -e 's/--modules=//'`
+ modules="$modules,$ms" ;;
+ --qemu-opts=*)
+ qs=`echo "$option" | sed -e 's/--qemu-opts=//'`
+ qemuopts="$qemuopts $qs" ;;
+ -*)
+ echo "Unrecognized option \`$option'" 1>&2
+ usage
+ exit 1
+ ;;
+ *)
+ if [ "x${source}" != x ] ; then
+ echo "too many parameters at the end" 1>&2
+ usage
+ exit 1
+ fi
+ source="${option}" ;;
+ esac
+done
+
+if [ "x${source}" = x ] ; then
+ tmpfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+ while read REPLY; do
+ echo $REPLY >> "${tmpfile}"
+ done
+ source="${tmpfile}"
+fi
+
+outfile1=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+"@builddir@/grub-shell" --qemu-opts="${qemuopts}" --modules=${modules} "${source}" >"${outfile1}"
+
+outfile2=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+bash "${source}" >"${outfile2}"
+
+if ! diff -q "${outfile1}" "${outfile2}" >/dev/null
+then
+ echo "${source}: GRUB and BASH outputs did not match (see diff -u ${outfile1} ${outfile2})"
+ status=1
+else
+ rm -f "${outfile1}" "${outfile2}"
+fi
+
+exit $status
+
+
diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in
new file mode 100644
index 0000000..93e9f51
--- /dev/null
+++ b/tests/util/grub-shell.in
@@ -0,0 +1,517 @@
+#! @BUILD_SHEBANG@
+set -e
+
+# Run GRUB script in a Qemu instance
+# Copyright (C) 2009,2010 Free Software Foundation, Inc.
+#
+# GRUB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+
+# Initialize some variables.
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+datarootdir="@datarootdir@"
+builddir="@builddir@"
+srcdir="@srcdir@"
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+
+# Force build directory components
+PATH="${builddir}:$PATH"
+export PATH
+
+trim=0
+
+# Usage: usage
+# Print the usage.
+usage () {
+ cat <<EOF
+Usage: $0 [OPTION] [SOURCE]
+Run GRUB script in a Qemu instance.
+
+ -h, --help print this message and exit
+ -v, --version print the version information and exit
+ --boot=[fd|hd|cd|net] boot method for Qemu instance
+ --modules=MODULES pre-load specified modules MODULES
+ --qemu=FILE Name of qemu binary
+ --disk=FILE Attach FILE as a disk
+ --qemu-opts=OPTIONS extra options to pass to Qemu instance
+ --files=FILES add files to the image
+ --mkrescue-arg=ARGS additional arguments to grub-mkrescue
+ --timeout=SECONDS set timeout
+ --trim trim firmware output
+
+$0 runs input GRUB script or SOURCE file in a Qemu instance and prints
+its output.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+. "${builddir}/grub-core/modinfo.sh"
+qemuopts="${GRUB_QEMU_OPTS}"
+serial_port=com0
+serial_null=
+halt_cmd=halt
+pseries=n
+disk="hda "
+case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
+ *-emu)
+ device_map=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+ boot=emu
+ console=console
+ disk=0
+ # To skip "Welcome to GRUB" and color setttings
+ trim=1
+ serial_port=
+ ;;
+ powerpc-ieee1275)
+ boot=hd
+ qemu=qemu-system-ppc
+ console=console
+ serial_port=escc-ch-b
+ serial_null="-serial null"
+ netbootext=elf
+ trim=1
+ ;;
+
+ sparc64-ieee1275)
+ boot=cd
+ qemu=qemu-system-sparc64
+ console=
+ serial_port=ieee1275/ttya
+ trim=1
+ qemuopts="$qemuopts -no-reboot"
+ halt_cmd=reboot
+ ;;
+
+ mips-qemu_mips)
+ boot=mips_qemu
+ qemu=qemu-system-mips
+ qemuopts="-M mips $qemuopts"
+ console=vga_text
+ ;;
+ mips-arc)
+ boot=cd
+ qemu=qemu-system-mips64
+ qemuopts="-M indy $qemuopts"
+ serial_port=arc/serial0/line0
+ console=
+ trim=1
+ ;;
+ mipsel-arc)
+ boot=cd
+ qemu=qemu-system-mips64el
+ qemuopts="-M magnum $qemuopts -no-reboot"
+ serial_port=arc/multi0/serial0
+ console=console
+ halt_cmd=reboot
+ trim=1
+ ;;
+ mipsel-qemu_mips)
+ boot=mipsel_qemu
+ qemu=qemu-system-mipsel
+ qemuopts="-M mips $qemuopts"
+ console=vga_text
+ ;;
+ mipsel-loongson)
+ boot=mipsel_fulong2e
+ qemu=qemu-system-mips64el
+ qemuopts="-M fulong2e $qemuopts"
+ console=
+ trim=1
+ ;;
+ i386-coreboot)
+ boot=coreboot
+ qemu=qemu-system-i386
+ console=vga_text
+ ;;
+ i386-multiboot)
+ boot=cd
+ qemu=qemu-system-i386
+ console=vga_text;;
+
+ i386-ieee1275)
+ boot=hd
+ qemu=qemu-system-i386
+ console=console
+ trim=1
+ disk="hdb "
+ ;;
+ i386-qemu)
+ boot=qemu
+ qemu=qemu-system-i386
+ console=vga_text;;
+
+ i386-pc)
+ boot=cd
+ qemu=qemu-system-i386
+ console=console
+ netbootext=0
+ ;;
+
+ i386-efi)
+ qemu=qemu-system-i386
+ boot=cd
+ console=console
+ trim=1
+ qemuopts="-bios OVMF-ia32.fd $qemuopts"
+ ;;
+ x86_64-efi)
+ qemu=qemu-system-x86_64
+ boot=cd
+ console=console
+ trim=1
+ qemuopts="-bios OVMF.fd $qemuopts"
+ ;;
+ arm64-efi)
+ qemu=qemu-system-aarch64
+ boot=hd
+ console=console
+ trim=1
+ qemuopts="-machine virt -cpu cortex-a57 -bios /usr/share/qemu-efi/QEMU_EFI.fd $qemuopts"
+ disk="device virtio-blk-device,drive=hd1 -drive if=none,id=hd1,file="
+ serial_port=
+ ;;
+ arm-efi)
+ qemu=qemu-system-arm
+ boot=hd
+ console=console
+ trim=1
+ qemuopts="-machine virt -bios /usr/share/ovmf-arm/QEMU_EFI.fd $qemuopts"
+ disk="device virtio-blk-device,drive=hd1 -drive if=none,id=hd1,file="
+ serial_port=efi0
+ ;;
+ *)
+ boot=hd
+ qemu=qemu-system-i386
+ console=console;;
+esac
+
+timeout=60
+mkimage_extra_arg=
+
+# Check the arguments.
+for option in "$@"; do
+ case "$option" in
+ -h | --help)
+ usage
+ exit 0 ;;
+ -v | --version)
+ echo "$0 (GNU GRUB ${PACKAGE_VERSION})"
+ exit 0 ;;
+ --trim)
+ trim=1
+ ;;
+ --debug)
+ debug=1 ;;
+ --modules=*)
+ ms=`echo "$option" | sed -e 's/--modules=//' -e 's/,/ /g'`
+ modules="$modules $ms" ;;
+ --files=*)
+ fls=`echo "$option" | sed -e 's/--files=//' -e 's/,/ /g'`
+ files="$files $fls" ;;
+ --mkrescue-arg=*)
+ mkr=`echo "$option" | sed -e 's/--mkrescue-arg=//' -e 's/,/ /g'`
+ mkrescue_args="$mkrescue_args $mkr" ;;
+ --qemu=*)
+ qemu=`echo "$option" | sed -e 's/--qemu=//' -e 's/,/ /g'`;;
+ --pseries)
+ qemu=qemu-system-ppc64
+ serial_port=ieee1275/hvterm
+ serial_null=
+ qemuopts="$qemuopts -M pseries -no-reboot"
+ trim=1
+ pseries=y
+ ;;
+ --qemu-opts=*)
+ qs=`echo "$option" | sed -e 's/--qemu-opts=//'`
+ qemuopts="$qemuopts $qs" ;;
+ --disk=*)
+ dsk=`echo "$option" | sed -e 's/--disk=//'`
+ if [ ${grub_modinfo_platform} = emu ]; then
+ echo "(hd$disk) $dsk" >> "$device_map"
+ disk="$((disk+1))"
+ else
+ if [ "$disk" = error ]; then
+ echo "Too many disks" 1>&2
+ exit 1;
+ fi
+ qemuopts="$qemuopts -$disk$dsk"
+ if [ "$disk" = "hda " ]; then
+ disk="hdb ";
+ elif [ "$disk" = "hdb " ]; then
+ # CDROM is hdc
+ disk="hdd "
+ elif [ "$disk" = "hdd " ]; then
+ # CDROM is hdc
+ disk=error
+ fi
+ fi
+ ;;
+ --timeout=*)
+ timeout=`echo "$option" | sed -e 's/--timeout=//'`
+ ;;
+
+ # Intentionally undocumented
+ --grub-mkimage-extra)
+ mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;;
+ --grub-mkimage-extra=*)
+ mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;;
+
+ --boot=*)
+ dev=`echo "$option" | sed -e 's/--boot=//'`
+ if [ "$dev" = "fd" ] ; then boot=fd;
+ elif [ "$dev" = "hd" ] ; then boot=hd;
+ elif [ "$dev" = "cd" ] ; then boot=cd;
+ elif [ "$dev" = "net" ] ; then boot=net;
+ elif [ "$dev" = "qemu" ] ; then boot=qemu;
+ elif [ "$dev" = "coreboot" ] ; then boot=coreboot;
+ elif [ "$dev" = "mips_qemu" ] ; then boot=mips_qemu;
+ elif [ "$dev" = "mipsel_qemu" ] ; then boot=mipsel_qemu;
+ elif [ "$dev" = "mipsel_fulong2e" ] ; then boot=mipsel_fulong2e;
+ else
+ echo "Unrecognized boot method \`$dev'" 1>&2
+ usage
+ exit 1
+ fi ;;
+ -*)
+ echo "Unrecognized option \`$option'" 1>&2
+ usage
+ exit 1 ;;
+ *)
+ if [ "x${source}" != x ] ; then
+ echo "too many parameters at the end" 1>&2
+ usage
+ exit 1
+ fi
+ source="${option}" ;;
+ esac
+done
+
+if [ "x${source}" = x ] ; then
+ tmpfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+ while read REPLY; do
+ echo "$REPLY" >> ${tmpfile}
+ done
+ source=${tmpfile}
+fi
+
+cfgfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+cat <<EOF >${cfgfile}
+grubshell=yes
+enable_progress_indicator=0
+export enable_progress_indicator
+EOF
+
+
+if [ "${grub_modinfo_platform}" != emu ]; then
+ echo insmod serial >>${cfgfile}
+fi
+
+if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275 ]; then
+ echo insmod escc >>${cfgfile}
+fi
+if [ "${serial_port}" != "" ]; then
+ echo "serial ${serial_port}" >>${cfgfile}
+ term="serial_${serial_port}"
+else
+ term=console
+fi
+
+cat <<EOF >>${cfgfile}
+terminfo -g 1024x1024 ${term} dumb
+terminal_input ${term}
+terminal_output ${term}
+EOF
+
+trim_head=664cbea8-132f-4770-8aa4-1696d59ac35c
+
+if [ $trim = 1 ]; then
+ echo "echo $trim_head" >>${cfgfile}
+fi
+
+rom_directory=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+
+for mod in ${modules}
+do
+ echo "insmod ${mod}" >> ${cfgfile}
+done
+
+cat <<EOF >>${cfgfile}
+source "\$prefix/testcase.cfg"
+# Stop serial output to suppress "ACPI shutdown failed" error.
+EOF
+# Attempt to switch to console on i386-ieee1275 causes "screen not found" message
+if [ x$console != x ] && [ x"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" != xi386-ieee1275 ]; then
+ echo "terminal_output $console" >>${cfgfile}
+fi
+echo "${halt_cmd}" >>${cfgfile}
+
+test -z "$debug" || echo "GRUB script: ${cfgfile}" >&2
+test -z "$debug" || echo "GRUB testcase script: ${tmpfile}" >&2
+test -z "$debug" || echo "Boot device: ${boot}" >&2
+
+isofile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+test -z "$debug" || echo "GRUB ISO file: ${isofile}" >&2
+test -z "$debug" || echo "GRUB ROM directory: ${rom_directory}" >&2
+
+if test -z "$debug"; then
+ qemuopts="${qemuopts} -nographic -monitor file:/dev/null"
+ # SeaBIOS 1.11.0 added support for VGA emulation over a serial port. If
+ # this is configured in SeaBIOS, then -nographic causes some extra junk to
+ # end up on the serial console, which interferes with our tests. This
+ # workaround unfortunately causes qemu to issue a warning 'externally
+ # provided fw_cfg item names should be prefixed with "opt/"', but there
+ # doesn't seem to be a better option.
+ qemuopts="${qemuopts} -fw_cfg name=etc/sercon-port,string=0"
+fi
+
+if [ x$boot != xnet ] && [ x$boot != xemu ]; then
+ pkgdatadir="@builddir@" "@builddir@/grub-mkrescue" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \
+ --rom-directory="${rom_directory}" \
+ --locale-directory="@srcdir@/po" \
+ --themes-directory="@srcdir@/themes" \
+ $mkimage_extra_arg ${mkrescue_args} \
+ "/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \
+ ${files} >/dev/null 2>&1
+fi
+if [ x$boot = xhd ]; then
+ if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm64-efi ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm-efi ]; then
+ device="device virtio-blk-device,drive=hd0 -drive if=none,id=hd0,file="
+ elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = mips-arc ]; then
+ device="hdb "
+ else
+ device="hda "
+ fi
+ bootdev="-boot c"
+fi
+if [ x$boot = xcd ]; then
+ if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm64-efi ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm-efi ]; then
+ device="device virtio-blk-device,drive=cd0 -drive if=none,id=cd0,media=cdrom,file="
+ elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275 ] && [ x$pseries != xy ] ; then
+ device="-drive if=ide,media=cdrom,file="
+ else
+ device="cdrom "
+ fi
+ bootdev="-boot d"
+fi
+if [ x$boot = xfd ]; then
+ device="fda "
+ bootdev="-boot a"
+fi
+
+if [ x$boot = xqemu ]; then
+ bootdev="-bios ${rom_directory}/qemu.img"
+ device="cdrom "
+fi
+
+if [ x$boot = xmipsel_qemu ]; then
+ bootdev="-kernel ${rom_directory}/mipsel-qemu_mips.elf"
+ device="cdrom "
+fi
+
+if [ x$boot = xmipsel_fulong2e ]; then
+ bootdev="-kernel ${rom_directory}/mipsel-loongson.elf -append machtype=lemote-fuloong-2e"
+ device="cdrom "
+fi
+
+if [ x$boot = xmips_qemu ]; then
+ bootdev="-kernel ${rom_directory}/mips-qemu_mips.elf"
+ device="cdrom "
+fi
+
+if [ x$boot = xcoreboot ]; then
+ imgfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+ cp "${GRUB_COREBOOT_ROM}" "${imgfile}"
+ "${GRUB_CBFSTOOL}" "${imgfile}" add-payload -f "${rom_directory}/coreboot.elf" -n fallback/payload
+ bootdev="-bios ${imgfile}"
+ device="cdrom "
+ test -z "$debug" || echo "Coreboot image: ${imgfile}" >&2
+fi
+
+if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = mipsel-arc ]; then
+ case "$boot" in
+ hd)
+ bootdev="-global ds1225y.filename=$GRUB_QEMU_MAGNUM_NVRAM_DIR/disk" ;;
+ *)
+ bootdev="-global ds1225y.filename=$GRUB_QEMU_MAGNUM_NVRAM_DIR/cdrom";;
+ esac
+fi
+
+do_trim ()
+{
+ if [ $trim = 1 ]; then
+ awk '{ if (have_head == 1) print $0; } /664cbea8-132f-4770-8aa4-1696d59ac35c/ { have_head=1; }'
+ else
+ cat
+ fi
+}
+
+copy_extra_files() {
+ _destdir="$1"
+ shift
+
+ # FIXME support '=' in file names
+ for _file in "$@"; do
+ _target="${_file%=*}"
+ _source="${_file#*=}"
+ [ -n "$_source" ] || _source="$_target"
+ _target="$_destdir/$_target"
+ _targetdir="$(dirname "$_target")"
+ [ -d "$_targetdir" ] || mkdir -p "$_targetdir"
+ cp "$_source" "$_target"
+ done
+}
+
+if [ x$boot = xnet ]; then
+ netdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
+ pkgdatadir="@builddir@" "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null
+ cp "${cfgfile}" "$netdir/boot/grub/grub.cfg"
+ cp "${source}" "$netdir/boot/grub/testcase.cfg"
+ [ -z "$files" ] || copy_extra_files "$netdir" $files
+ timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | do_trim
+elif [ x$boot = xemu ]; then
+ rootdir="$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")"
+ grubdir="$rootdir/boot/grub"
+ mkdir -p "$grubdir/fonts"
+ mkdir -p "$grubdir/themes"
+ mkdir -p "$grubdir/locale"
+ test -f "@builddir@/"unicode.pf2 && cp "@builddir@/"unicode.pf2 "$grubdir/fonts/unicode.pf2"
+ cp -R "@srcdir@/themes/starfield" "$grubdir/themes/starfield"
+ for file in "@srcdir@/po/"*.gmo; do
+ if [ -f "$file" ]; then
+ cp "$file" "$grubdir/locale/"
+ fi
+ done
+ cp "${cfgfile}" "$grubdir/grub.cfg"
+ cp "${source}" "$grubdir/testcase.cfg"
+ [ -z "$files" ] || copy_extra_files "$rootdir" $files
+ roottar="$(mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")"
+ (cd "$rootdir"; tar cf "$roottar" .)
+ @builddir@/grub-core/grub-emu -m "$device_map" --memdisk "$roottar" -r memdisk -d "/boot/grub" | tr -d "\r" | do_trim
+ test -n "$debug" || rm -rf "$rootdir"
+ test -n "$debug" || rm -f "$roottar"
+else
+ timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} | cat | tr -d "\r" | do_trim
+fi
+if [ x$boot = xcoreboot ]; then
+ test -n "$debug" || rm -f "${imgfile}"
+fi
+test -n "$debug" || rm -f "${isofile}"
+test -n "$debug" || rm -rf "${rom_directory}"
+test -n "$debug" || rm -f "${tmpfile}" "${cfgfile}"
+exit 0
+
+