Allow GRUB to mount ext2/3/4 filesystems that have the encryption feature.
[grub.git] / tests / util / grub-fs-tester.in
1 #!@BUILD_SHEBANG@
2
3 set -e
4
5 fs="$1"
6
7 GRUBFSTEST="@builddir@/grub-fstest"
8
9 tempdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
10
11 # This wrapper is to ease insertion of valgrind or time statistics
12 run_it () {
13     LC_ALL=C "$GRUBFSTEST" "$@"
14 }
15
16 range() {
17     range_counter="$1"
18     while test "$range_counter" -le "$2"; do
19         echo "$range_counter"
20         range_counter="$((range_counter + $3))"
21     done
22 }
23
24 powrange() {
25     range_counter="$1"
26     while test "$range_counter" -le "$2"; do
27         echo "$range_counter"
28         range_counter="$((range_counter * 2))"
29     done
30 }
31
32 run_grubfstest () {
33     need_images=
34     for i in $(range 0 $((NEED_IMAGES_N-1)) 1); do
35         need_images="$need_images $FSIMAGEP${i}.img";
36     done
37
38     run_it -c $NEED_IMAGES_N $need_images  "$@"
39 }
40
41 # OS LIMITATION: GNU/Linux has no AFS support, so we use a premade image and a reference tar file. I.a. no multiblocksize test
42
43 MINLOGSECSIZE=9
44 MAXLOGSECSIZE=9
45 case x"$fs" in
46     xntfs*)
47         MINLOGSECSIZE=8
48         MAXLOGSECSIZE=12;;
49     xvfat*|xmsdos*)
50         MINLOGSECSIZE=9
51             #  OS LIMITATION: It could go up to 32768 but Linux rejects sector sizes > 4096
52         MAXLOGSECSIZE=12;;
53     xext*)
54         MINLOGSECSIZE=8
55         MAXLOGSECSIZE=12;;
56     xbtrfs*)
57         MINLOGSECSIZE=8
58             #  OS LIMITATION: It could go up to 32768 but Linux rejects sector sizes > 4096
59         MAXLOGSECSIZE=12;;
60     xxfs)
61         MINLOGSECSIZE=9
62             # OS LIMITATION: GNU/Linux doesn't accept > 4096
63         MAXLOGSECSIZE=12;;
64     xxfs_crc)
65         MINLOGSECSIZE=9
66             # OS LIMITATION: GNU/Linux doesn't accept > 1024
67         MAXLOGSECSIZE=10;;
68     xzfs*)
69             # OS LIMITATION: zfs-fuse hangs when creating zpool with sectors <=256B.
70         MINLOGSECSIZE=9
71             # OS LIMITATION: zfs-fuse fails with >= 32K sectors.
72         # OS limitation: zfs-fuse always uses ashift=9 with loop devices
73         MAXLOGSECSIZE=9;;
74 esac
75 for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do
76     SECSIZE="$((1 << LOGSECSIZE))"
77     MINBLKSIZE=512
78     MAXBLKSIZE=512
79     BLKSTEP=0
80     case x"$fs" in
81         xntfs*)
82             MINBLKSIZE=$SECSIZE
83             MAXBLKSIZE=65536
84             if [ x"$SECSIZE" = x256 ]; then
85                 MINBLKSIZE=512
86                 MAXBLKSIZE=32768
87             fi
88             ;;
89         xvfat* | xmsdos*)
90             MINBLKSIZE=$SECSIZE
91             MAXBLKSIZE=$((128*SECSIZE))
92             ;;
93         xexfat*)
94             MINBLKSIZE=$SECSIZE
95                 # It could go further but it requires more and more space
96             MAXBLKSIZE=8286208
97             ;;
98         xhfs)
99             MINBLKSIZE=512
100             # OS LIMITATION: should be 1048576 but linux hangs on unmnount with
101             # >= 524288
102             MAXBLKSIZE=262144
103             ;;
104         xhfsplus | xhfsplus_casesens | xhfsplus_wrap)
105             MINBLKSIZE=512
106             MAXBLKSIZE=1048576
107             ;;
108         xnilfs2)
109             # nilfs2 supports blocksizes from 1024 to 4096
110             # but non-4096 results in kernel oops in some cases,
111             # avoid it.
112             MINBLKSIZE=4096
113             MAXBLKSIZE=4096
114             ;;
115         xsfs*)
116             MINBLKSIZE=512
117             MAXBLKSIZE=4096
118             ;;
119         xaffs | xaffs_intl)
120             MINBLKSIZE=512
121             MAXBLKSIZE=4096
122             ;;
123         xreiserfs*)
124             MINBLKSIZE=512
125                 # OS LIMITATION: 8192 isn't supported.
126             MAXBLKSIZE=4096
127             ;;
128         x"mdraid"*)
129             MINBLKSIZE=4096
130                 # OS LIMITATION: Linux oopses with >=32768K
131             MAXBLKSIZE=$((16384*1024))
132             ;;
133         x"lvm_raid1"* | x"lvm_raid4" | x"lvm_raid5" | x"lvm_raid6")
134                 # OS LIMITATION: Linux crashes with less than 16384
135             MINBLKSIZE=16384
136                 # Could go further but what's the point?
137             MAXBLKSIZE=$((65536*1024))
138             ;;
139         x"lvm_mirrorall")
140             MINBLKSIZE=2048
141                 # Could go further but what's the point?
142             MAXBLKSIZE=$((65536*1024))
143             ;;
144         x"lvm_mirror1")
145             MINBLKSIZE=4096
146                 # Could go further but what's the point?
147             MAXBLKSIZE=$((65536*1024))
148             ;;
149         x"lvm_stripe")
150             MINBLKSIZE=4096
151                 # Could go further but what's the point?
152             MAXBLKSIZE=$((65536*1024))
153             ;;
154         x"lvm"*)
155             MINBLKSIZE=1024
156                 # Could go further but what's the point?
157             MAXBLKSIZE=$((65536*1024))
158             ;;
159        xext4_encrypt)
160            # OS LIMITATION: Linux currently only allows the 'encrypt' feature
161            # in combination with block_size = PAGE_SIZE (4096 bytes on x86).
162            MINBLKSIZE=$(getconf PAGE_SIZE)
163            MAXBLKSIZE=$MINBLKSIZE
164            ;;
165         xext*)
166             MINBLKSIZE=1024
167             if [ $MINBLKSIZE -lt $SECSIZE ]; then
168                 MINBLKSIZE=$SECSIZE
169             fi
170             MAXBLKSIZE=4096
171             ;;
172         xsquash*)
173             MINBLKSIZE=4096
174             MAXBLKSIZE=1048576;;
175         xxfs)
176             MINBLKSIZE=$SECSIZE
177                 # OS Limitation: GNU/Linux doesn't accept > 4096
178             MAXBLKSIZE=4096;;
179         xxfs_crc)
180             # OS Limitation: GNU/Linux doesn't accept != 1024
181             MINBLKSIZE=1024
182             MAXBLKSIZE=1024;;
183         xudf)
184             MINBLKSIZE=1024
185             MAXBLKSIZE=4096;;
186         xbfs)
187             MINBLKSIZE=1024
188             MAXBLKSIZE=8192;;
189         xufs*)
190             MINBLKSIZE=4096
191                 # OS Limitation: Linux rejects 65536 blocks.
192             MAXBLKSIZE=32768;;
193         xminix3)
194                 # OS LIMITATION: Linux rejects non-power-of-two blocks.
195                 # OS LIMITATION: Linux rejects > 4096.
196             MINBLKSIZE=1024
197             MAXBLKSIZE=4096;;
198     esac
199     if test "$BLKSTEP" -eq 0; then
200         blksizes="$(powrange "$MINBLKSIZE" "$MAXBLKSIZE")"
201     else
202         blksizes="$(range "$MINBLKSIZE" "$MAXBLKSIZE" "$BLKSTEP")"
203     fi
204     for BLKSIZE in $blksizes; do
205         MAXDEVICES=1
206         MINDEVICES=1
207         export fs
208         case x"$fs" in
209             x"zfs_raidz" | x"zfs_stripe" | x"zfs_mirror" | xbtrfs_raid0 \
210                 | xbtrfs_raid1 | x"mdraid"*"_raid4" | x"mdraid"*"_raid5" \
211                 | x"mdraid"*"_linear" \
212                 | x"mdraid"*"_raid10" | xlvm_raid1* | xlvm_mirror1 | xlvm_mirrorall)
213                 MINDEVICES=2
214                 MAXDEVICES=7
215                 ;;
216             xbtrfs_raid10)
217                 MINDEVICES=4
218                 MAXDEVICES=7
219                 ;;
220             x"zfs_raidz2"| xlvm_raid5 | xlvm_raid4)
221                 MINDEVICES=3
222                 MAXDEVICES=7;;
223             x"zfs_raidz3" | x"mdraid"*"_raid6")
224                 MINDEVICES=4
225                 MAXDEVICES=7;;
226             xlvm_raid6)
227                 MINDEVICES=5
228                 MAXDEVICES=7;;
229             x"mdraid"*"_raid0" | x"mdraid"*"_raid1" | x"lvm" | xlvm_stripe)
230                 MINDEVICES=1
231                 MAXDEVICES=7;;
232         esac
233
234         for NDEVICES in $(range "$MINDEVICES" "$MAXDEVICES" 1); do
235             export NDEVICES
236             unset FSIMAGEP
237             FSIMAGEP="${tempdir}/${fs}_${SECSIZE}_${BLKSIZE}_${NDEVICES}_"
238             export FSIMAGEP
239             unset NEED_IMAGES;
240
241             case x$fs in
242             # RAID 1 has to work with even one device of the set.
243                 xzfs_mirror | x"mdraid"*"_raid1" | xlvm_mirrorall | xlvm_raid1all)
244                     NEED_IMAGES_N=1;;
245             # Degrade raidz by removing 3 devices
246                 xzfs_raidz3)
247                     NEED_IMAGES_N=$((NDEVICES-3));;
248              # Degrade raidz by removing 2 devices
249                 xzfs_raidz2 | x"mdraid"*"_raid6" | x"lvm_raid6")
250                     NEED_IMAGES_N=$((NDEVICES-2));;
251             # Degrade raidz and btrfs RAID1 by removing one device
252                 xbtrfs_raid1 | xbtrfs_raid10 | xzfs_raidz | x"mdraid"*"_raid4" \
253                     | x"mdraid"*"_raid5" | x"mdraid"*"_raid10" | xlvm_mirror1 \
254                     | x"lvm_raid1" | x"lvm_raid4" | x"lvm_raid5")
255                     NEED_IMAGES_N=$((NDEVICES-1));;
256                 *)
257                     NEED_IMAGES_N=$NDEVICES;;
258             esac
259             export NEED_IMAGES_N
260
261             MNTPOINTRO="${tempdir}/${fs}_ro"
262             MNTPOINTRW="${tempdir}/${fs}_rw"
263             MOUNTOPTS=""
264             MOUNTFS="$fs"
265             MASTER="${tempdir}/master"
266             FSLABEL="grub_;/testé莭莽茝😁киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewrewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfew"
267             CFILESRC=
268             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
269                 if test -f "$cand" ; then
270                     CFILESRC="$cand"
271                     break
272                 fi
273             done
274             if test "$CFILESRC" = "" ; then
275                 echo "Couldn't find compressible file" >&2
276                 exit 1
277             fi
278             case x"$fs" in
279                     # FS LIMITATION: 8.3 names
280                 xmsdos*)
281                     CFILE="american.eng";;
282                 xiso9660)
283                     CFILE="american_english";;
284                 *)
285                     CFILE="american-english";;
286             esac
287         # OS LIMITATION: Limited by NAME_MAX (usually 255) in GNU/Linux
288             LONGNAME="qwertzuiopasdfghjklyxcvbnm1234567890qwertzuiopasdfghjklyxcvbnm1234567890oiewqfiewioqoiqoiurqruewqoiuwoieoiiuewqroreqiufieiuwrnureweriuvceoiroiewqoiricdsalkcndsakfirefoiwqeoircorejwoijfreoijojoiewjfwnfcoirenfoirefnreoifenoiwfnoi"
289             rm -rf "$MASTER"
290
291             case x"$fs" in
292                 # FS LIMITATION: HFS+ label is at most 255 UTF-16 chars
293                 # OS LIMITATION: Linux HFS+ tools check UTF-8 length and don't
294                 # handle out-of-BMP characters
295                 x"hfsplus" | x"hfsplus_casesens" | x"hfsplus_wrap")
296                     FSLABEL="grub_;/testé䏌䐓䏕киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoiq"
297                     ;;
298             # FS LIMITATION: btrfs label is at most 255 UTF-8 chars
299                 x"btrfs"*)
300                     FSLABEL="grub_;/testé莭莽😁киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoi";;
301
302             # FS LIMITATION: exfat is at most 15 UTF-16 chars
303                 x"exfat")
304                     FSLABEL="géт ;/莭莽😁кир";;
305             # FS LIMITATION: ntfs label is at most ?? UTF-16 chars
306                 x"ntfs"*)
307                     FSLABEL="grub_;/testéтi u莭😁茝кириrewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvniwnivrewiuvcrewvnuewvrrrewniureifiuewifjiww";;
308             # FS LIMITATION: nilfs2 label is at most 80 UTF-8 characters
309                 x"nilfs2")
310                     FSLABEL="grub_;/testéтi u😁莽茝кириrewfceniuewruevrewnuuireurevueurnievrewfne";;
311                     # FS LIMITATION: afs and iso9660 label is at most 32 UTF-8 characters
312                 x"afs" | xiso9660 | xrockridge | xrockridge_joliet\
313                      | xiso9660_1999 | xrockridge_1999 | xrockridge_joliet_1999)
314                      FSLABEL="gr_;/é莭莽😁кирит u";;
315                     # FS LIMITATION: bfs label is at most 32 UTF-8 characters
316                     # OS LIMITATION: bfs label can't contain ; or /
317                 x"bfs")
318                     FSLABEL="grub_é莭莽😁кирит u";;
319                 # FS LIMITATION: Joliet label is at most 16 UTF-16 characters
320                 # OS LIMITATION: xorriso doesn't handle out-of-BMP characters
321                 xjoliet | xjoliet_1999)
322                     FSLABEL="g;/_é䏌䐓䏕䎛䎾䏴кит u"
323                     #FSLABEL="g;/_é莭莽😁кит u"
324                     ;;
325             # FS LIMITATION: reiserfs, extN and jfs label is at most 16 UTF-8 characters
326                 x"reiserfs_old" | x"reiserfs" | x"ext"* | x"lvm"* | x"mdraid"* | x"jfs" | x"jfs_caseins")
327                     FSLABEL="g;/éт 莭😁";;
328             # FS LIMITATION: No underscore, space, semicolon, slash or international characters in UFS* in label. Limited to 32 UTF-8 characters
329                 x"ufs1" | x"ufs1_sun" | x"ufs2")
330                     FSLABEL="grubtest""ieurrucnenreeiurueurewf";;
331             # FS LIMITATION: XFS label is at most 12 UTF-8 characters
332                 x"xfs"|x"xfs_crc")
333                     FSLABEL="géт 😁к";;
334             # FS LIMITATION: FAT labels limited to 11 characters, no  international characters or lowercase
335                 x"vfat"* | xmsdos*)
336                     FSLABEL="GRUBTEST ;_";;
337             # FS LIMITATION: AFFS is latin1. At most 29 characters
338                 x"affs" | xaffs_intl)
339                     FSLABEL="grub_tt? #*w;/e£@¡¤½¾{[]}<>.,";;
340             # FS LIMITATION: SFS is latin1. At most 30 characters
341                 x"sfs"*)
342                     FSLABEL="GRUB tt öäüé;/àèç åø¿ª©þð׫»µ¬";;
343             # FS LIMITATION:  HFS is Mac-Roman. At most 27 characters
344                 x"hfs")
345                     FSLABEL="grub_t;/estéàèèéie fiucnree";;
346                 # FS LIMITATION: UDF label is either up to 127 latin1 characters or 63 UTF-16 ones
347                 # OS LIMITATION: Linux UDF tools force ASCII label ...
348                 x"udf")
349                     FSLABEL="grub_;/testurewfceniuewruevrewnuuireurevueurnievr";;
350             # FS LIMITATION:  ZFS doesn't accept non-ASCII in label
351             # FIXME: since this is used as a path component for mount it's very limited in length
352                 xzfs_* | xzfs)
353                     FSLABEL="grub_testieufiue r";;
354             esac
355             case x"$fs" in
356                 xmdraid*)
357                     DISKSIZE=314572800;;
358                 xlvm*)
359                     LVMBLKMUL=$(((5800 * 1048576) / (8 * BLKSIZE * NDEVICES)))
360                     DISKSIZE=$((8*BLKSIZE*LVMBLKMUL));;
361                     # FS LIMITATION: some fs have disk size limit
362                 x"vfat12" | xmsdos12)
363                     DISKSIZE=$((4000*BLKSIZE));;
364                 x"vfat12a" | xmsdos12a)
365                     if [ $BLKSIZE -ge 2048 ]; then
366                         DISKSIZE=$((2500*BLKSIZE))
367                     else
368                         DISKSIZE=$((3000*BLKSIZE))
369                     fi
370                     if [ $DISKSIZE -gt $((60000*SECSIZE)) ]; then
371                         DISKSIZE=$((60000*SECSIZE))
372                     fi;;
373                 x"vfat16" | xmsdos16)
374                     DISKSIZE=$((65000*BLKSIZE));;
375                 x"vfat16a" | xmsdos16a)
376                     DISKSIZE=$((60000*SECSIZE))
377                     ;;
378                 *)
379                     DISKSIZE=10737418240;;
380             esac
381
382             if [ $DISKSIZE -ge $(((5800/NDEVICES)*1048576)) ]; then
383                 DISKSIZE=$(((5800/NDEVICES)*1048576))
384             fi
385
386             case x"$fs" in
387                 xvfat* | xmsdos* | xexfat* | xhfs | xhfsplus | xhfsplus_wrap | xaffs \
388                     | xaffs_intl | xjfs_caseins | xsfs_caseins \
389                     | xzfs_caseins | xiso9660)
390                     CASESENS=n;;
391                 *)
392                     CASESENS=y;;
393             esac
394
395             BIGBLOCKCNT=$((5000 * 1048576))
396             case x"$fs" in
397                     # FS LIMITATION: small filesystems
398                 x"vfat12" | xmsdos12)
399                     if [ $BLKSIZE -le 4096 ]; then
400                         BIGBLOCKCNT=0
401                     elif [ $BLKSIZE = 8192 ]; then
402                         BIGBLOCKCNT=1500000
403                     else
404                         BIGBLOCKCNT=$((2000*BLKSIZE))
405                     fi
406                     ;;
407                 x"vfat12a" | xmsdos12a)
408                     if [ $BLKSIZE -le 4096 ] || [ $((128*SECSIZE)) = $BLKSIZE ]; then
409                         BIGBLOCKCNT=0
410                     else
411                         BIGBLOCKCNT=700000
412                     fi;;
413                 x"vfat16a" | xmsdos16a)
414                     if [ $((128*SECSIZE)) = $BLKSIZE ]; then
415                         BIGBLOCKCNT=0
416                     else
417                         BIGBLOCKCNT=$((2500*SECSIZE))
418                     fi
419                     ;;
420                 x"vfat16" | xmsdos16)
421                     BIGBLOCKCNT=$((25000 * BLKSIZE))
422                     if [ $BIGBLOCKCNT -gt 4294967295 ]; then
423                         BIGBLOCKCNT=4294967295
424                     fi
425                     ;;
426                 x"minix")
427                     BIGBLOCKCNT=30000000;;
428
429                 xexfat)
430                         # Big blocks waste really a lot of space.
431                         # Not much is left.
432                     if [ $BLKSIZE = 2097152 ]; then
433                         BIGBLOCKCNT=4500000000
434                     fi
435                     if [ $BLKSIZE = 4194304 ]; then
436                         BIGBLOCKCNT=3500000000
437                     fi
438                     ;;
439                     # FS LIMITATION: romfs image is limited to 4G.
440                 x"romfs")
441                     BIGBLOCKCNT=$((4000 * 1048576));;
442                     # FS LIMITATION: These FS have uint32 as file size field
443                 x"vfat"* | xmsdos* | x"cpio_crc" | x"cpio_newc" | x"cpio_bin" | x"cpio_hpbin" | xsfs*)
444                     BIGBLOCKCNT=4294967295;;
445                     # FS LIMITATION: These FS have int32 as file size field
446                     # FIXME: not so sure about AFFS
447                     # OS LIMITATION: minix2/minix3 could be formatted in a way to permit more.
448                 x"minix3" | x"minix2" | x"hfs"| x"affs" | xaffs_intl | xreiserfs_old | xext2_old)
449                     BIGBLOCKCNT=$((16#7fffffff));;
450
451                     # FS LIMITATION: redundant storage
452                     # We have only limited space. Mirroring multiplies it very effectively.
453                 xmdraid* | xlvm* | xzfs_mirror | xbtrfs_raid1)
454                     BIGBLOCKCNT=$((100 * 1048576));;
455                     # We already test the FS for big files separately. Save some time here.
456                 x"zfs_raid"* | x"zfs_stripe"* | x"zfs_mirror"* | x"btrfs_raid"*)
457                     BIGBLOCKCNT=$((100 * 1048576));;
458
459                     # OS LIMITATION: bfs_fuse bugs beyond that
460                 xbfs)
461                     BIGBLOCKCNT=$((800 * 1048576));;
462             esac
463
464             NOSYMLINK=n
465             case x"$fs" in
466         # FS LIMITATION: no symlinks on FAT, exFAT, HFS, plain ISO9660 and Joliet
467         # OS LIMITATION: ntfs-3g  creates interix symlinks which aren't real symlinks
468                 x"vfat"* | xmsdos* | x"hfs" | x"exfat" | x"ntfs"* \
469                     | xiso9660 | xjoliet| xiso9660_1999 | xjoliet_1999)
470                     NOSYMLINK=y;;
471             esac
472             NOHARDLINK=n
473             case x"$fs" in
474                     # FS LIMITATION: no hardlinks on BFS, exfat, fat, hfs and SFS
475                 xbfs | xexfat | x"vfat"* | xmsdos* | xhfs | xsfs | xsfs_caseins)
476                     NOHARDLINK=y;;
477                     # GRUB LIMITATION: no hardlink support on newc and hfs+
478                 xcpio_crc | xcpio_newc | xhfsplus*)
479                     NOHARDLINK=y;;
480             esac
481
482                 # FS LIMITATION: some filesystems limit file name size
483             case x"$fs" in
484                 x"cpio_ustar")
485                     LONGNAME="`echo $LONGNAME |head -c 99`";;
486                 x"hfs")
487                     LONGNAME="`echo $LONGNAME |head -c 31`";;
488                 x"minix" | x"minix2" | x"affs" | xaffs_intl | xiso9660)
489                     LONGNAME="`echo $LONGNAME |head -c 30`";;
490                 x"sfs"*)
491                     LONGNAME="`echo $LONGNAME |head -c 105`";;
492                 x"minix3")
493                     LONGNAME="`echo $LONGNAME |head -c 60`";;
494                 x"udf")
495                     LONGNAME="`echo $LONGNAME |head -c 192`";;
496                     # GRUB LIMITATION: GRUB prefers Joliet over ISO9660:1999
497                 xjoliet | xjoliet_1999)
498                     LONGNAME="`echo $LONGNAME |head -c 103`";;
499                 xiso9660_1999)
500                     LONGNAME="`echo $LONGNAME |head -c 207`";;
501                     # FS LIMITATION: 8.3
502                 xmsdos*)
503                     LONGNAME="qwertzui.opa";;
504             esac
505             NOFILETIME=n
506             NOFSTIME=n
507             case x"$fs" in
508             # FIXME: Not sure about BtrFS, NTFS, JFS, AFS, UDF and SFS. Check it.
509         # FS LIMITATION: as far as I know those FS don't store their last modification date.
510                 x"jfs_caseins" | x"jfs" | x"xfs" | x"xfs_crc" | x"btrfs"* | x"reiserfs_old" | x"reiserfs" \
511                     | x"bfs" | x"afs" \
512                     | x"tarfs" | x"cpio_"* | x"minix" | x"minix2" \
513                     | x"minix3" | x"ntfs"* | x"udf" | x"sfs"*)
514                     NOFSTIME=y;;
515                     # OS LIMITATION: Linux doesn't update fstime.
516                 # OS LIMITATION: Linux apparently uses localtime instead of UTC
517                 xhfs)
518                     NOFILETIME=y; NOFSTIME=y;;
519             # GRUB LIMITATION:  FAT and exFAT use localtime. Unusable for GRUB
520                 x"vfat"* | x"msdos"* | x"exfat")
521                     NOFILETIME=y; NOFSTIME=y;;
522         # FS LIMITATION: romfs has no timestamps.
523                 x"romfs")
524                     NOFILETIME=y; NOFSTIME=y;;
525             esac
526
527             NOFSLABEL=n
528             case x"$fs" in
529                     # FS LIMITATION: these filesystems have no label.
530                 x"cpio_"* | x"tarfs" | x"squash4_"* | x"minix" | x"minix2" \
531                     | x"minix3" | xreiserfs_old)
532                     NOFSLABEL=y;;
533             esac
534
535             PDIRCOMPNUM=210
536             PDIR2COMPNUM=210
537
538             case x$fs in
539                     # OS LIMITATION: bfs_fuse bugs beyond that
540                 xbfs)
541                     PDIRCOMPNUM=10
542                     PDIR2COMPNUM=10;;
543                     # OS LIMITATION: Linux supports only inline symlinks
544                 xudf)
545                     if [ $BLKSIZE = 1024 ]; then
546                         PDIR2COMPNUM=113
547                     fi ;;
548                     # FS LIMITATION: at most 255 on path length
549                     # FS LIMITATION: at most 100 on symlink length
550                 xcpio_ustar)
551                     PDIRCOMPNUM=84
552                     PDIR2COMPNUM=30;;
553                     # OS LIMITATION: Linux supports only symlink at most one block long on reiserfs
554                 xreiserfs | xreiserfs_old)
555                     if [ $BLKSIZE = 512 ]; then
556                         PDIR2COMPNUM=114
557                     fi ;;
558                     # FS LIMITATION: SFS assumes that symlink
559                     # with header fit in one block.
560                     # FIXME: not sure about it.
561                 xsfs | xsfs_caseins)
562                     if [ $BLKSIZE = 512 ]; then
563                         PDIR2COMPNUM=147
564                     fi ;;
565                     # FS LIMITATION: AFFS assumes that symlink
566                     # with rather larger header fit in one block.
567                     # FIXME: not sure about it.
568                 xaffs | xaffs_intl)
569                     if [ $BLKSIZE = 512 ]; then
570                         PDIR2COMPNUM=97
571                     fi ;;
572             esac
573
574
575             PDIR=""
576                 # OS LIMITATION: Limited by PATH_MAX (usually 1024)
577             for i in $(range 0 $((PDIRCOMPNUM-1)) 1); do
578                 PDIR="$PDIR/$i";
579                 if test $((i%3)) = 0; then
580                     PDIR="$PDIR/"
581                 fi
582             done
583
584             PDIR2=""
585                 # OS LIMITATION: Limited by PATH_MAX (usually 1024)
586             for i in $(range 0 $((PDIR2COMPNUM-1)) 1); do
587                 PDIR2="${PDIR2}/$i";
588                 if test $((i%3)) = 0; then
589                     PDIR2="${PDIR2}/"
590                 fi
591             done
592
593             PFIL="p.img"
594
595             unset LODEVICES
596             GENERATED=n
597             LODEVICES=
598             MOUNTDEVICE=
599             
600             case x"$fs" in
601                 x"tarfs" | x"cpio_"*| x"ziso9660" | x"romfs" | x"squash4_"*\
602                     | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet \
603                     | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 \
604                     | xrockridge_joliet_1999)
605                     MNTPOINTRW="$MASTER"
606                     MNTPOINTRO="$MASTER"
607                     GENERATED=y
608                     mkdir -p "$MASTER";;
609                     # No mkfs for GNU/Linux. Just unpack preformatted empty image
610                 *)
611                     mkdir -p "$MNTPOINTRW"
612                     mkdir -p "$MNTPOINTRO"
613                     for i in $(range 0 $((NDEVICES-1)) 1); do
614                         dd if=/dev/zero of="$FSIMAGEP${i}.img" count=1 bs=1 seek=$((DISKSIZE-1)) &> /dev/null
615                         LODEVICE="$(losetup -f)"
616                         LODEVICES="$LODEVICES $LODEVICE"
617                         losetup "$LODEVICE" "$FSIMAGEP${i}.img"
618                         if test "$i" = 0; then
619                             MOUNTDEVICE="$LODEVICE"
620                         fi
621                     done ;;
622             esac
623
624             case x"$fs" in
625                 x"afs")
626                     ;;
627                 x"btrfs")
628                     "mkfs.btrfs" -s $SECSIZE -L "$FSLABEL" "${MOUNTDEVICE}" ;;
629                 x"btrfs_zlib" | x"btrfs_lzo")
630                     "mkfs.btrfs" -s $SECSIZE -L "$FSLABEL" "${MOUNTDEVICE}"
631                     MOUNTOPTS="compress=${fs/btrfs_/},"
632                     MOUNTFS="btrfs"
633                     ;;
634                 x"btrfs_raid0")
635                     "mkfs.btrfs" -s $SECSIZE -d raid0 -m raid0 -L "$FSLABEL" $LODEVICES
636                     MOUNTFS="btrfs"
637                     ;;
638                 x"btrfs_raid1")
639                     "mkfs.btrfs" -s $SECSIZE -d raid1 -m raid1 -L "$FSLABEL" $LODEVICES
640                     MOUNTFS="btrfs"
641                     ;;
642                 x"btrfs_raid10")
643                     "mkfs.btrfs" -s $SECSIZE -d raid10 -m raid10 -L "$FSLABEL" $LODEVICES
644                     MOUNTFS="btrfs"
645                     ;;
646                 x"btrfs_single")
647                     "mkfs.btrfs" -s $SECSIZE -d single -L "$FSLABEL" $LODEVICES
648                     MOUNTFS="btrfs"
649                     ;;
650                 x"exfat")
651                     "mkfs.$fs" -s $((BLKSIZE/512)) -n "$FSLABEL" "${MOUNTDEVICE}"
652                     MOUNTOPTS="iocharset=utf8,"
653                     MOUNTFS="exfat-fuse";;
654                 x"minix")
655                     "mkfs.minix" "${MOUNTDEVICE}"
656                     ;;
657         # mkfs.hfs and mkfs.hfsplus don't fill UUID.
658                 x"hfsplus")
659                     "mkfs.hfsplus" -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}"
660                     dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#468)) conv=notrunc count=8 ;;
661                 x"hfsplus_wrap")
662                     "mkfs.hfsplus" -w -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}"
663                     dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#468)) conv=notrunc count=8
664                     MOUNTFS="hfsplus";;
665                 x"hfsplus_casesens")
666                     "mkfs.hfsplus" -s -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}"
667                     dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#468)) conv=notrunc count=8
668                     MOUNTFS="hfsplus";;
669                 x"hfs")
670                     "mkfs.hfs" -b $BLKSIZE -v "`echo $FSLABEL |recode utf8..macroman`" -h "${MOUNTDEVICE}"
671                     dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#474)) conv=notrunc count=8
672                     MOUNTOPTS="iocharset=utf8,codepage=macroman,"
673                     ;;
674                 x"vfat"*|xmsdos*)
675                     BITS="${fs/vfat/}"
676                     BITS="${BITS/msdos/}"
677                     if [ "x${BITS:2:1}" = xa ]; then
678                         A=-A
679                     else
680                         A=
681                     fi
682                     "mkfs.vfat" -a $A -S $SECSIZE -s $((BLKSIZE/SECSIZE)) -F "${BITS:0:2}" -n "$FSLABEL" "${MOUNTDEVICE}"
683                     MOUNTOPTS="iocharset=utf8,codepage=437,"
684                     MOUNTFS="$(echo "$fs"|sed 's,[0-9]*a\?$,,')";;
685                 x"minix2")
686                     "mkfs.minix" -v "${MOUNTDEVICE}"
687                     MOUNTFS="minix";;
688                 x"minix3")
689                     "mkfs.minix" -B $BLKSIZE -3 "${MOUNTDEVICE}"
690                     MOUNTFS="minix";;
691                 x"ntfs"*)
692                     "mkfs.ntfs" -s "$SECSIZE" -c "$BLKSIZE" -L "$FSLABEL" -Q -q "${MOUNTDEVICE}"
693                     MOUNTOPTS="iocharset=utf8,compression,"
694                     MOUNTFS="ntfs-3g";;
695                 x"udf")
696                     "mkudffs" --utf8 -b $BLKSIZE --lvid="$FSLABEL" "${MOUNTDEVICE}"
697                     MOUNTOPTS="iocharset=utf8,bs=$BLKSIZE,";;
698                 x"ufs2")
699                     "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 2 "${MOUNTDEVICE}"
700                     MOUNTOPTS="ufstype=ufs2,"
701                     MOUNTFS="ufs";;
702                 x"ufs1")
703                     "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 1 "${MOUNTDEVICE}"
704                     MOUNTOPTS="ufstype=44bsd,"
705                     MOUNTFS="ufs";;
706                 x"ufs1_sun")
707                     "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 1 "${MOUNTDEVICE}"
708                     MOUNTOPTS="ufstype=sun,"
709                     MOUNTFS="ufs";;
710                 x"zfs")
711                     "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${MOUNTDEVICE}"
712                     sleep 1
713                     "zfs" create "$FSLABEL"/"grub fs"
714                     sleep 1;;
715                 x"zfs_caseins")
716                     "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${MOUNTDEVICE}"
717                     sleep 1
718                     "zfs" create -o casesensitivity=insensitive "$FSLABEL"/"grub fs"
719                     sleep 1;;
720                 x"zfs_lzjb" | xzfs_gzip | xzfs_zle)
721                     "zpool" create -O compression=${fs/zfs_/} -R "$MNTPOINTRW" "$FSLABEL" "${MOUNTDEVICE}"
722                     sleep 1
723                     "zfs" create -o compression=${fs/zfs_/} "$FSLABEL"/"grub fs"
724                     sleep 1;;
725                 x"zfs_raidz")
726                     "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz1 $LODEVICES
727                     sleep 1
728                     "zfs" create "$FSLABEL"/"grub fs"
729                     sleep 1;;
730                 x"zfs_raidz2")
731                     "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz2 $LODEVICES
732                     sleep 1
733                     "zfs" create "$FSLABEL"/"grub fs"
734                     sleep 1;;
735                 x"zfs_raidz3")
736                     "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz3 $LODEVICES
737                     sleep 1
738                     "zfs" create "$FSLABEL"/"grub fs"
739                     sleep 1;;
740                 x"zfs_mirror")
741                     "zpool" create -R "$MNTPOINTRW" "$FSLABEL" mirror $LODEVICES
742                     sleep 1
743                     "zfs" create "$FSLABEL"/"grub fs"
744                     sleep 1;;
745                 x"zfs_stripe")
746                     "zpool" create -R "$MNTPOINTRW" "$FSLABEL" $LODEVICES
747                     sleep 1
748                     "zfs" create "$FSLABEL"/"grub fs"
749                     sleep 1;;
750                 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_"*)
751                     INSTDEVICE=/dev/null;;
752                 x"reiserfs")
753                     "mkfs.reiserfs" --format=3.6 -b $BLKSIZE -l "$FSLABEL" -q "${MOUNTDEVICE}" ;;
754                 x"reiserfs_old")
755                     "mkfs.reiserfs" --format=3.5 -b $BLKSIZE -l "$FSLABEL" -q "${MOUNTDEVICE}"
756                     MOUNTFS=reiserfs;;
757                 x"jfs")
758                     "mkfs.jfs" -L "$FSLABEL" -q "${MOUNTDEVICE}"
759                     MOUNTOPTS="iocharset=utf8,";;
760                 x"jfs_caseins")
761                     "mkfs.jfs" -O -L "$FSLABEL" -q "${MOUNTDEVICE}"
762                     MOUNTFS=jfs
763                     MOUNTOPTS="iocharset=utf8,";;
764                 x"mdraid"*)
765                     mdadm -C --chunk=$((BLKSIZE/1024)) --force -e "${fs:6:1}.${fs:7:1}" "/dev/md/${fs}_${NDEVICES}" --level="${fs:13}" --raid-devices="$NDEVICES" $LODEVICES
766                     MOUNTDEVICE="/dev/md/${fs}_${NDEVICES}"
767                     MOUNTFS=ext2
768                     "mkfs.ext2" -L "$FSLABEL" -q "${MOUNTDEVICE}" ;;
769                 x"lvm"*)
770                     for lodev in $LODEVICES; do
771                         pvcreate "$lodev"
772                     done
773                     vgcreate -s $((BLKSIZE/1024))K grub_test $LODEVICES
774                     if [ x$fs = xlvm ] ; then
775                         lvcreate -l "$((NDEVICES*7*LVMBLKMUL))" -n testvol grub_test
776                     elif [ x$fs = xlvm_stripe ] ; then
777                         lvcreate -l "$((NDEVICES*7*LVMBLKMUL))" -i "$NDEVICES" -n testvol grub_test
778                     elif [ x$fs = xlvm_mirror1 ] || [ x$fs = xlvm_raid1 ] ; then
779                         lvcreate -m 1 -l "$((NDEVICES*2*LVMBLKMUL))" --type "${fs/lvm_/}" -n testvol grub_test
780                     elif [ x$fs = xlvm_mirrorall ] ; then
781                         lvcreate -m "$((NDEVICES-1))" -l "$((6*LVMBLKMUL))" --type mirror -n testvol grub_test
782                     elif [ x$fs = xlvm_raid1all ] ; then
783                         # Until version 2.02.103 LVM counts metadata segments
784                         # twice when checking available space. Reduce segment
785                         # count to work around it.
786                         lvcreate -m "$((NDEVICES-1))" -l "$((6*LVMBLKMUL - 1))" --type raid1 -n testvol grub_test
787                     elif [ x$fs = xlvm_raid4 ] || [ x$fs = xlvm_raid5 ]; then
788                         lvcreate -l "$(((NDEVICES-1) * 5*LVMBLKMUL))" -i "$((NDEVICES-1))" --type "${fs/lvm_/}" -n testvol grub_test
789                     elif [ x$fs = xlvm_raid6 ]; then
790                         lvcreate -l "$(((NDEVICES-2) * 5*LVMBLKMUL))" -i "$((NDEVICES-2))" --type "${fs/lvm_/}" -n testvol grub_test
791                     fi
792                     MOUNTDEVICE="/dev/mapper/grub_test-testvol"
793                     MOUNTFS=ext2
794                     "mkfs.ext2" -L "$FSLABEL" -q "${MOUNTDEVICE}"  ;;
795                 xnilfs2)
796                     "mkfs.nilfs2" -L "$FSLABEL" -b $BLKSIZE  -q "${MOUNTDEVICE}" ;;
797                 xext2_old)
798                     MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext2" -r 0 -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}"
799                     MOUNTFS=ext2
800                     ;;
801                 xext4_metabg)
802                     MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext4" -O meta_bg,^resize_inode -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}"
803                     MOUNTFS=ext4
804                     ;;
805                xext4_encrypt)
806                    MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext4" -O encrypt -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}"
807                    MOUNTFS=ext4
808                    ;;
809                 xext*)
810                     MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.$fs" -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" ;;
811                 xxfs)
812                     "mkfs.xfs" -m crc=0 -b size=$BLKSIZE -s size=$SECSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" ;;
813                 xxfs_crc)
814                     MOUNTFS="xfs"
815                     "mkfs.xfs" -m crc=1 -b size=$BLKSIZE -s size=$SECSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" ;;
816                 *)
817                     echo "Add appropriate mkfs command here"
818                     exit 1
819                     ;;
820             esac
821             BASEFILE="1.img"
822             NASTYFILE=".?*\\!\"#%@\$%&'()+ ,-.:;<=>^{_}[]\`|~."
823             case x"$fs" in
824
825                     # FS LIMITATION: AFFS and SFS don't accept :
826                 xsfs*)
827                     NASTYFILE=".?*\\!\"#%@\$%&'()+ ,-.;<=>^{_}[]\`|~.";;
828                     # FS LIMITATION: AFFS is limited in file name length (30)
829                 x"affs" | xaffs_intl)
830                     NASTYFILE=".?*\\!\"#@\$'()+ ,-;<=>^{_}[]\`|~.";;
831             # FS LIMITATION: hfs, minix and minix2 are limited in file name length (30 or 31)
832                 x"hfs" | x"minix" | x"minix2")
833                     NASTYFILE=".?*\\!\"#@\$&'()+ ,-:;<=>{}[]\`|~.";;
834             # FS LIMITATION: FAT doesn't accept ?, *, \, ", :,  <, >, |
835             # FS LIMITATION: FAT discards dots at the end.
836                 x"vfat"* | x"exfat")
837                     NASTYFILE=".!#%@\$%&'()+ ,-.;=^{_}[]\`~";;
838             # FS LIMITATION: 8.3 limitations apply
839                 x"msdos"*)
840                     NASTYFILE="!#%@\$%&.;=^";;
841                     # FS LIMITATION: No ' ', '*', '/', ':', ';', '?', '\\' in joliet
842                     # GRUB LIMITATION: GRUB prefers Joliet over ISO9660:1999
843                 xjoliet | xjoliet_1999)
844                     NASTYFILE=".!\"#%@\$%&'()+,-.<=>^{_}[]\`|~.";;
845                     # FS LIMITATION: iso9660 accepts only [0-9A-Z_]*, 32 characters at most
846                 xiso9660)
847                     NASTYFILE="0123456789_acefghijknopqrvwxyz";;
848             esac
849
850             case x"$fs" in
851                     # FS LIMITATION: HFS, AFFS and SFS use legacy codepage (mac-roman or latin1)
852                 x"sfs"* | x"hfs" | x"affs" | xaffs_intl)
853                     IFILE="éàèüöäëñ"
854                     ISYM="ëñéüöäàè"
855                     ;;
856                     # FS LIMITATION: filename length limitation.
857                 x"minix" | x"minix2")
858                     IFILE="éàèüö😁ñкиΕλκά"
859                     ISYM="Ελκάкиéà😁öäëñ"
860                     ;;
861                 xminix3)
862                     IFILE="éàèüöäëñкирица莭茝Ελλικά😁😜😒"
863                     ISYM="Ελλικά😁😜😒莭茝кирицаéàèüöäëñ";;
864                 # GRUB LIMITATION: HFS+ uses NFD. GRUB doesn't handle NF conversion.
865                 # OS LIMITATION: Linux doesn't handle out-of-BMP characters for UTF-16
866                 x"hfsplus" | x"hfsplus_casesens" | x"hfsplus_wrap")
867                     IFILE="éàèüöäëñкирилица䏌䐓䏕Ελληνικα̍䏌䐓䏕"
868                     ISYM="Ελληνικα̍кирилица䏌䐓䏕éàèüöäëñ䏌䐓䏕"
869                     ;;
870                     # GRUB LIMITATION: On case-insensitive ZFS isn't supported with non-uppercase characters
871                 xzfs_caseins)
872                     IFILE="ÉÀÈÜÖÄËÑКИРИЛИЦА莭莽茝ΕΛΛΗΝΙΚΆ😁😜😒"
873                     ISYM="ΕΛΛΗΝΙΚΆКИРИЛИЦА😁😜😒ÉÀÈÜÖÄËÑ莭莽茝";;
874                     # FS LIMITATION: 8.3 CP437
875                 x"msdos"*)
876                     IFILE="éàèüöäëñ.éàè"
877                     ;;
878                     # FS LIMITATION: iso9660 is ASCII-only.
879                 x"iso9660")
880                     IFILE="abcdefghijkmmnop"
881                     ;;
882                 # OS LIMITATION: Linux doesn't handle out-of-BMP characters for UTF-16
883                 # OS LIMITATION: xorriso doesn't handle out-of-BMP characters
884                 xjoliet | xjoliet_1999 | x"vfat"* | x"jfs"* | x"udf"*)
885                     IFILE="éàèüöäëñкирилица䏌䐓䏕Ελληνικά䏌䐓䏕"
886                     ISYM="Ελληνικάкирилица䏌䐓䏕éàèüöäëñ䏌䐓䏕";;
887                 *)
888                     IFILE="éàèüöäëñкирилица莭莽茝Ελληνικά😁😜😒"
889                     ISYM="Ελληνικάкирилица😁😜😒éàèüöäëñ莭莽茝";;
890             esac
891             BIGFILE="big.img"
892             BASESYM="sym"
893             BASEHARD="hard"
894             SSYM="///sdir////ssym"
895             USYM="///sdir////usym"
896             LONGSYM="longsym"
897             PSYM="psym"
898             OSDIR=""
899             GRUBDEVICE=loop0
900             case x"$fs" in
901                 xmdraid*)
902                     GRUBDEVICE="mduuid/`mdadm --detail --export $MOUNTDEVICE | grep MD_UUID=|sed 's,MD_UUID=,,g;s,:,,g'`";;
903                 xlvm*)
904                     GRUBDEVICE="lvm/grub_test-testvol";;
905             esac
906             GRUBDIR="($GRUBDEVICE)"
907             case x"$fs" in
908                 x"zfs"*)
909                     OSDIR="grub fs/"
910                     GRUBDIR="($GRUBDEVICE)/grub fs@";;
911                 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)
912                     ;;
913                 *)
914                     if ! mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRW" -o ${MOUNTOPTS}${SELINUXOPTS}rw  ; then
915                         echo "MOUNT FAILED."
916                         for lodev in $LODEVICES; do
917                             while ! losetup -d "$lodev"; do
918                                 sleep 1
919                             done
920                         done
921                         for i in $(range 0 $((NDEVICES-1)) 1); do
922                             rm "$FSIMAGEP${i}.img"
923                         done
924                         exit 1;
925                     fi
926                     ;;
927             esac
928             case x"$fs" in
929                     # FS LIMITATION: redundant storage
930                 xmdraid* | xlvm*)
931                     BLOCKCNT=1048576;;
932                 x"zfs_raid"* | x"zfs_stripe"* | x"zfs_mirror"* | x"btrfs_raid"*)
933                     BLOCKCNT=1048576;;
934
935                     # FS LIMITATION: small filesystems
936                 x"vfat16a" | x"msdos16a")
937                     BLOCKCNT=65536;;
938                 x"vfat12a" | xmsdos12a)
939                     BLOCKCNT=32768;;
940                 xminix)
941                     BLOCKCNT=2621440;;
942                 xvfat16 | xmsdos16)
943                     if [ $BLKSIZE = 512 ] || [ $BLKSIZE = 1024 ]; then
944                         BLOCKCNT=1048576
945                     else
946                         BLOCKCNT=5242880
947                     fi
948                     ;;
949                 xvfat12 | xmsdos12)
950                     BLOCKCNT=$((100*BLKSIZE))
951                     if [ $BLOCKCNT -gt 5242880 ]; then
952                         BLOCKCNT=5242880;
953                     fi
954                     ;;
955                 *)
956                     BLOCKCNT=5242880;;
957             esac
958             # Make sure file is not exact multiple of block size. This helps to force
959             # tail packing in case of squash4.
960             : $((BLOCKCNT--))
961             case x"$fs" in
962                 x"ntfscomp")
963                     setfattr -h -v 0x00000800 -n system.ntfs_attrib_be "$MNTPOINTRW/$OSDIR";;
964             esac
965                 # OS LIMITATION: No AFS support under GNU/Linux
966             mkdir "$MNTPOINTRW/$OSDIR/sdir"
967             mkdir -p "$MNTPOINTRW/$OSDIR/$PDIR"
968             "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/sdir/2.img"
969             "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$BASEFILE"
970             "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$NASTYFILE"
971             "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$IFILE"
972             "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$LONGNAME"
973             "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$PDIR/$PFIL"
974             if [ $PDIR != $PDIR2 ]; then
975                 "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/${PDIR2}/$PFIL"
976             fi
977             "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/CaSe"
978             if [ x$CASESENS = xy ]; then
979                 "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/cAsE"
980             fi
981             if (test x$fs = xvfat12a || test x$fs = xmsdos12a) && test x$BLKSIZE = x131072; then
982                     # With this config there isn't enough space for full copy.
983                     # Copy as much as we can
984                 cp "${CFILESRC}" "$MNTPOINTRW/$OSDIR/${CFILE}" &> /dev/null;
985             else
986
987                 cp "${CFILESRC}" "$MNTPOINTRW/$OSDIR/${CFILE}";
988
989             fi
990
991             if [ x$NOSYMLINK != xy ]; then
992                 ln -s "$BASEFILE" "$MNTPOINTRW/$OSDIR/$BASESYM"
993                 ln -s "2.img" "$MNTPOINTRW/$OSDIR/$SSYM"
994                 ln -s "../1.img" "$MNTPOINTRW/$OSDIR/$USYM"
995                 ln -s "$LONGNAME" "$MNTPOINTRW/$OSDIR/$LONGSYM"
996                 ln -s "${PDIR2}/$PFIL" "$MNTPOINTRW/$OSDIR/$PSYM"
997                 ln -s "$IFILE" "$MNTPOINTRW/$OSDIR/$ISYM"
998             fi
999             if [ x$NOHARDLINK != xy ]; then
1000                 ln "$MNTPOINTRW/$OSDIR/$BASEFILE" "$MNTPOINTRW/$OSDIR/$BASEHARD"
1001             fi
1002
1003             case x"$fs" in
1004                 x"afs")
1005                     ;;
1006                 x"zfs"*)
1007                     while ! zpool export "$FSLABEL" ; do
1008                         sleep 1;
1009                     done
1010                     sleep 2
1011                     ;;
1012                 x"tarfs")
1013                     (cd "$MASTER"; tar cf "${FSIMAGEP}0.img" .) ;;
1014                 x"cpio_"*)
1015                     (cd "$MASTER"; find . | cpio -o -H "$(echo ${fs} | sed 's@^cpio_@@')" > "${FSIMAGEP}0.img" ) ;;
1016                 x"ziso9660")
1017                     FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
1018                     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" ;;
1019                 x"iso9660")
1020                     FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
1021                     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"  ;;
1022                 x"joliet")
1023                     FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
1024                     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"  ;;
1025                 x"rockridge")
1026                     FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
1027                     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"  ;;
1028                 x"rockridge_joliet")
1029                     FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
1030                     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"  ;;
1031                 x"iso9660_1999")
1032                     FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
1033                     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"  ;;
1034                 x"joliet_1999")
1035                     FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
1036                     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"  ;;
1037                 x"rockridge_1999")
1038                     FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
1039                     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"  ;;
1040                 x"rockridge_joliet_1999")
1041                     FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00);
1042                     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"  ;;
1043                 x"romfs")
1044                     genromfs -V "$FSLABEL" -f "${FSIMAGEP}0.img" -d "$MASTER" ;;
1045                 xsquash4_*)
1046                     echo mksquashfs "$MASTER" "${FSIMAGEP}0.img" -always-use-fragments -comp "${fs/squash4_/}" -b $BLKSIZE
1047                     mksquashfs "$MASTER" "${FSIMAGEP}0.img" -always-use-fragments -comp "${fs/squash4_/}" -b $BLKSIZE ;;
1048                 x"bfs")
1049                     sleep 1
1050                     fusermount -u "$MNTPOINTRW"
1051                     ;;
1052                 xlvm*)
1053                     sleep 1
1054                     for try in $(range 0 20 1); do
1055                         if umount "$MNTPOINTRW" ; then
1056                             break;
1057                         fi
1058                         sleep 1;
1059                     done
1060                     UMOUNT_TIME=$(date -u "+%Y-%m-%d %H:%M:%S")
1061                     sleep 1
1062                     vgchange -a n grub_test
1063                     ;;
1064                 xmdraid*)
1065                     sleep 1
1066                     for try in $(range 0 20 1); do
1067                         if umount "$MNTPOINTRW" ; then
1068                             break;
1069                         fi
1070                         sleep 1;
1071                     done
1072                     UMOUNT_TIME=$(date -u "+%Y-%m-%d %H:%M:%S")
1073                     sleep 1
1074                     mdadm --stop /dev/md/"${fs}_$NDEVICES"
1075                     ;;
1076                 *)
1077                     sleep 1
1078                     for try in $(range 0 20 1); do
1079                         if umount "$MNTPOINTRW" ; then
1080                             break;
1081                         fi
1082                         sleep 1;
1083                     done
1084                     ;;
1085             esac
1086             sleep 1
1087
1088             case x"$fs" in
1089                 x"zfs"*)
1090                     "zpool" import -d /dev -R "$MNTPOINTRO" "$FSLABEL"
1091                     ;;
1092                 x"tarfs")
1093                     ;;
1094                 x"cpio_"*)
1095                     ;;
1096                 x"ziso9660")
1097                     ;;
1098                 xiso9660 | xrockridge | xjoliet | xrockridge_joliet)
1099                     ;;
1100                 xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999)
1101                     ;;
1102                 x"romfs")
1103                     ;;
1104                 xsquash4_*)
1105                     ;;
1106                 xlvm*)
1107                     vgchange -a y grub_test
1108                     sleep 1
1109                     mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;;
1110                 xmdraid*)
1111                     mdadm --assemble /dev/md/"${fs}_$NDEVICES" $LODEVICES
1112                     sleep 1
1113                     mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;;
1114                 *)
1115                     mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;;
1116             esac
1117
1118             run_grubfstest ls -- -la
1119             case x"$fs" in
1120                 x"zfs"*)
1121                     LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/grub fs@/");;
1122                 *)
1123                     LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/");;
1124             esac
1125             if echo "$LSROUT" | grep -F " $BASEFILE" | grep "$BLOCKCNT" > /dev/null; then
1126                 :
1127             else
1128                 echo LIST FAIL
1129                 echo "$LSROUT"
1130                 TZ=UTC ls -l "$MNTPOINTRO"
1131                 exit 1
1132             fi
1133
1134             if echo "$LSROUT" | grep -F " $NASTYFILE" | grep "$BLOCKCNT"> /dev/null; then
1135                 :
1136             else
1137                 echo NLIST FAIL
1138                 echo "$LSROUT"
1139                 TZ=UTC ls -lA "$MNTPOINTRO"
1140                 exit 1
1141             fi
1142
1143             if echo "$LSROUT" | grep -F " $IFILE" | grep "$BLOCKCNT"> /dev/null; then
1144                 :
1145             else
1146                 echo ILIST FAIL
1147                 echo "$LSROUT"
1148                 TZ=UTC ls -l "$MNTPOINTRO"
1149                 exit 1
1150             fi
1151
1152             if echo "$LSROUT" | grep -F " $LONGNAME" | grep "$BLOCKCNT"> /dev/null; then
1153                 :
1154             else
1155                 echo LONG LIST FAIL
1156                 echo "$LSROUT"
1157                 TZ=UTC ls -l "$MNTPOINTRO"
1158                 exit 1
1159             fi
1160
1161             if [ x$NOFILETIME != xy ]; then
1162                 filtime=$(TZ=UTC ls --time-style=+%Y%m%d%H%M%S -l -d "$MNTPOINTRO/$OSDIR/$BASEFILE"|awk '{print $6; }')
1163                 if echo "$LSROUT" | grep -F "$filtime $BASEFILE" > /dev/null; then
1164                     :
1165                 else
1166                     echo TIME FAIL
1167                     echo "$LSROUT"
1168                     TZ=UTC ls -l "$MNTPOINTRO"
1169                     exit 1
1170                 fi
1171
1172                 filtime=$(TZ=UTC ls --time-style=+%Y%m%d%H%M%S -l -d "$MNTPOINTRO/$OSDIR/$LONGNAME"|awk '{print $6; }')
1173                 if echo "$LSROUT" | grep -F "$filtime $LONGNAME" > /dev/null; then
1174                     :
1175                 else
1176                     echo LONG TIME FAIL
1177                     echo "$LSROUT"
1178                     TZ=UTC ls -l "$MNTPOINTRO"
1179                     exit 1
1180                 fi
1181             fi
1182
1183             case x"$fs" in
1184                 x"zfs"*)
1185                     LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/grub fs@/.");;
1186                 *)
1187                     LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/.");;
1188             esac
1189             if echo "$LSROUT" | grep -F " $BASEFILE" | grep "$BLOCKCNT" > /dev/null; then
1190                 :
1191             else
1192                 echo DOT IN ROOTDIR FAIL
1193                 echo "$LSROUT"
1194                 TZ=UTC ls -l "$MNTPOINTRO"
1195                 exit 1
1196             fi
1197
1198             case x"$fs" in
1199                 x"zfs"*)
1200                     ;;
1201                 *)
1202                     LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/..");
1203                     if echo "$LSROUT" | grep -F " $BASEFILE" | grep "$BLOCKCNT" > /dev/null; then
1204                         :
1205                     else
1206                         echo DOTDOT IN ROOTDIR FAIL
1207                         echo "$LSROUT"
1208                         TZ=UTC ls -l "$MNTPOINTRO"
1209                         exit 1
1210                     fi
1211                     ;;
1212             esac
1213
1214             case x"$fs" in
1215                 x"zfs"*)
1216                     LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/////sdir");;
1217                 *)
1218                     LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/////sdir");;
1219             esac
1220             if echo "$LSROUT" | grep -F " 2.img" | grep $BLOCKCNT > /dev/null; then
1221                 :
1222             else
1223                 echo SLIST FAIL
1224                 echo "$LSROUT"
1225                 TZ=UTC ls -l "$MNTPOINTRO/sdir"
1226                 exit 1
1227             fi
1228
1229             case x"$fs" in
1230                 x"zfs"*)
1231                     LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/$PDIR");;
1232                 *)
1233                     LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/$PDIR");;
1234             esac
1235             if echo "$LSROUT" | grep -F " p.img" | grep $BLOCKCNT > /dev/null; then
1236                 :
1237             else
1238                 echo PLIST FAIL
1239                 echo "$LSROUT"
1240                 TZ=UTC ls -l "$MNTPOINTRO/$PDIR"
1241                 exit 1
1242             fi
1243
1244             case x"$fs" in
1245                 x"zfs"*)
1246                     LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/sdir/.");;
1247                 *)
1248                     LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/sdir/.");;
1249             esac
1250             if echo "$LSROUT" | grep -F " 2.img" | grep $BLOCKCNT > /dev/null; then
1251                 :
1252             else
1253                 echo DOT IN SUBDIR FAIL
1254                 echo "$LSROUT"
1255                 TZ=UTC ls -l "$MNTPOINTRO/$OSDIR/sdir"
1256                 exit 1
1257             fi
1258
1259             case x"$fs" in
1260                 x"zfs"*)
1261                     LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/sdir/../sdir");;
1262                 *)
1263                     LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/sdir/../sdir");;
1264             esac
1265             if echo "$LSROUT" | grep -F " 2.img" | grep $BLOCKCNT > /dev/null; then
1266                 :
1267             else
1268                 echo DOTDOT IN SUBDIR FAIL
1269                 echo "$LSROUT"
1270                 TZ=UTC ls -l "$MNTPOINTRO/$OSDIR/ssdir"
1271                 exit 1
1272             fi
1273
1274             LSOUT=`run_grubfstest ls -- -l "($GRUBDEVICE)"`
1275             if [ x"$NOFSLABEL" = xy ]; then
1276                 :
1277             elif echo "$LSOUT" | grep -F "Label \`$FSLABEL'" > /dev/null; then
1278                 :
1279             else
1280                 echo LABEL FAIL
1281                 echo "$LSOUT"
1282                 blkid "${MOUNTDEVICE}"
1283                 exit 1
1284             fi
1285
1286     # Inconsistencies between GRUB and blkid.
1287             case x"$fs" in
1288                 x"iso9660" | x"ziso9660" | xrockridge | xjoliet | xrockridge_joliet | x"iso9660_1999" | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) ;;
1289                 x"zfs"*)
1290                     for lodev in $LODEVICES; do
1291                         FSUUID=$(printf "%016x\n" $(blkid -o export "$lodev" |grep -F UUID=|sed s,UUID=,,g))
1292                         if [ "$FSUUID" != 0000000000000000 ]; then
1293                             break;
1294                         fi
1295                     done;;
1296                 *)
1297                     FSUUID=`blkid -o export "${MOUNTDEVICE}" |grep -F UUID=|sed s,UUID=,,g`
1298                     ;;
1299             esac
1300             case x"$fs" in
1301                 x"hfs"*)
1302                     GRUBUUID="`run_grubfstest xnu_uuid "$GRUBDEVICE"`"
1303                     if [ x"$GRUBUUID" = x"$FSUUID" ]; then
1304                         :
1305                     else
1306                         echo UUID FAIL
1307                         echo "$LSOUT"
1308                         echo "$GRUBUUID"
1309                         for lodev in $LODEVICES; do
1310                             blkid "$lodev"
1311                         done
1312                         exit 1
1313                     fi
1314                     ;;
1315         # FS LIMITATION: romfs, cpio, tar, squash4, minix, AFS, old reiserfs and minix2
1316         # have no UUID.
1317                     # GRUB LIMITATION: use creation date for squash4, AFFS and SFS?
1318                     # GRUB LIMITATION: use tags serials on UDF?
1319                     # GRUB LIMITATION: use root ctime on cpio, tar, minix*, UDF, reiserfs_old?
1320                     # GRUB LIMITATION: Support Atari UUIDs
1321                 x"romfs" | x"cpio_"* | x"tarfs" | x"squash4_"* | x"minix" \
1322                     | x"minix2" | x"minix3" | x"affs" | xaffs_intl \
1323                     | x"udf" | xvfat12a | xvfat16a | xmsdos12a | xmsdos16a | xafs | xsfs* \
1324                     | xreiserfs_old)
1325                     ;;
1326                 *)
1327                     if [ x"$FSUUID" = x ]; then
1328                         echo "Warning: blkid couldn't retrieve UUID"
1329                     elif echo "$LSOUT" | grep -F 'UUID '"$FSUUID"' ' > /dev/null; then
1330                         :
1331                     else
1332                         echo UUID FAIL
1333                         echo "$FSUUID"
1334                         echo "$LSOUT"
1335                         blkid "${MOUNTDEVICE}"
1336                         exit 1
1337                     fi
1338                     ;;
1339             esac
1340
1341             if [ x$NOFSTIME != xy ]; then
1342                 case x$fs in
1343                     xiso9660 | xziso9660 | xrockridge | xjoliet | xrockridge_joliet | xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999)
1344                         FSTIME="$(date -d "$(echo ${FSUUID} | awk -F - '{ print $1"-"$2"-"$3" "$4":"$5":"$6 ;}')" '+%Y-%m-%d %H:%M:%S')";;
1345                     xlvm*|xmdraid*)
1346                         # With some abstractions like mdraid flushing to disk
1347                         # may be delayed for a long time.
1348                         FSTIME="$UMOUNT_TIME";;
1349                     *)
1350                         FSTIME="$(TZ=UTC ls --time-style="+%Y-%m-%d_%H:%M:%S" -l -d "${FSIMAGEP}0.img"|awk '{print $6; }'|sed 's,_, ,g')";;
1351                 esac
1352                 # With some abstractions like mdraid computing of UMOUNT_TIME
1353                 # is not precise. Account for small difference here.
1354                 FSTIMEM1="$(date -d "$FSTIME UTC -1 second" -u "+%Y-%m-%d %H:%M:%S")"
1355                 FSTIMEM2="$(date -d "$FSTIME UTC -2 second" -u "+%Y-%m-%d %H:%M:%S")"
1356                 FSTIMEM3="$(date -d "$FSTIME UTC -3 second" -u "+%Y-%m-%d %H:%M:%S")"
1357
1358                 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
1359                     :
1360                 else
1361                     echo FSTIME FAIL
1362                     echo "$FSTIME"
1363                     echo "$LSOUT"
1364                     exit 1
1365                 fi
1366             fi
1367
1368             if [ x$NOHARDLINK != xy ]; then
1369                 if run_grubfstest cmp "$GRUBDIR/$BASEHARD" "$MNTPOINTRO/$OSDIR/$BASEFILE"  ; then
1370                     :
1371                 else
1372                     echo HARDLINK FAIL
1373                     exit 1
1374                 fi
1375             fi
1376
1377             if [ x$NOSYMLINK != xy ]; then
1378                 if run_grubfstest cmp "$GRUBDIR/$BASESYM" "$MNTPOINTRO/$OSDIR/$BASEFILE"  ; then
1379                     :
1380                 else
1381                     echo SYMLINK FAIL
1382                     exit 1
1383                 fi
1384                 if run_grubfstest cmp "$GRUBDIR/$LONGSYM" "$MNTPOINTRO/$OSDIR/$LONGNAME"  ; then
1385                     :
1386                 else
1387                     echo LONG SYMLINK FAIL
1388                     exit 1
1389                 fi
1390                 if run_grubfstest cmp "$GRUBDIR/$ISYM" "$MNTPOINTRO/$OSDIR/$IFILE"  ; then
1391                     :
1392                 else
1393                     echo INTL SYMLINK FAIL
1394                     exit 1
1395                 fi
1396                 if run_grubfstest cmp "$GRUBDIR/$SSYM" "$MNTPOINTRO/$OSDIR/////sdir/////2.img"  ; then
1397                     :
1398                 else
1399                     echo SDIR SYMLINK FAIL
1400                     exit 1
1401                 fi
1402                 if run_grubfstest cmp "$GRUBDIR/$USYM" "$MNTPOINTRO/$OSDIR/1.img"  ; then
1403                     :
1404                 else
1405                     echo SDIR SYMLINK FAIL
1406                     exit 1
1407                 fi
1408                 if run_grubfstest cmp "$GRUBDIR/$PSYM" "$MNTPOINTRO/$OSDIR/${PDIR2}/$PFIL"  ; then
1409                     :
1410                 else
1411                     echo PATH LONG SYMLINK FAIL
1412                     exit 1
1413                 fi
1414             fi
1415
1416             if run_grubfstest cmp "$GRUBDIR/$BASEFILE" "$MNTPOINTRO/$OSDIR/$BASEFILE"  ; then
1417                 :
1418             else
1419                 echo READ FAIL
1420                 exit 1
1421             fi
1422             if run_grubfstest cmp "$GRUBDIR/$NASTYFILE" "$MNTPOINTRO/$OSDIR/$NASTYFILE"  ; then
1423                 :
1424             else
1425                 echo NREAD FAIL
1426                 exit 1
1427             fi
1428                 # Reference archive contains original name
1429             if run_grubfstest cmp "$GRUBDIR/$LONGNAME" "$MNTPOINTRO/$OSDIR/$LONGNAME"  ; then
1430                 :
1431             else
1432                 echo LONG NAME READ FAIL
1433                 exit 1
1434             fi
1435             if run_grubfstest cmp "$GRUBDIR/////sdir/////2.img" "$MNTPOINTRO/$OSDIR/sdir/2.img"  ; then
1436                 :
1437             else
1438                 echo LONG NAME READ FAIL
1439                 exit 1
1440             fi
1441             if run_grubfstest cmp "$GRUBDIR/$IFILE" "$MNTPOINTRO/$OSDIR/$IFILE"  ; then
1442                 :
1443             else
1444                 echo IREAD FAIL
1445                 exit 1
1446             fi
1447             if run_grubfstest cmp "$GRUBDIR/$PDIR/$PFIL" "$MNTPOINTRO/$OSDIR/$PDIR/$PFIL"  ; then
1448                 :
1449             else
1450                 echo PREAD FAIL
1451                 echo cmp "$GRUBDIR/$PDIR/$PFIL" "$MNTPOINTRO/$OSDIR/$PDIR/$PFIL"
1452                 exit 1
1453             fi
1454             ok=true
1455             if ! run_grubfstest cmp "$GRUBDIR/${CFILE}" "$MNTPOINTRO/$OSDIR/${CFILE}"  ; then
1456                 ok=false;
1457             fi
1458             if  test x$ok = xtrue; then
1459                 :
1460             else
1461                 echo CREAD FAIL
1462                 exit 1
1463             fi
1464
1465             if [ x$CASESENS = xy ]; then
1466                 if run_grubfstest cmp "$GRUBDIR/CaSe" "$MNTPOINTRO/$OSDIR/CaSe"  ; then
1467                     :
1468                 else
1469                     echo CASE1 READ FAIL
1470                     exit 1
1471                 fi
1472                 if run_grubfstest cmp "$GRUBDIR/cAsE" "$MNTPOINTRO/$OSDIR/cAsE"  ; then
1473                     :
1474                 else
1475                     exit 1
1476                 fi
1477                 if cmp "$MNTPOINTRO/$OSDIR/cAsE" "$MNTPOINTRO/$OSDIR/CaSe" > /dev/null ; then
1478                     exit 1
1479                 fi
1480                 if  test x$ok = xtrue; then
1481                     :
1482                 else
1483                     echo CASE READ FAIL
1484                     exit 1
1485                 fi
1486             else
1487                 # OS LIMITATION: Linux make FAT (partially) case-sensitive...
1488                 # ISO9660 is generated and master doesn't change
1489                 case x$fs in
1490                     xiso9660 | xvfat*)
1491                         CASEX=CaSe;;
1492                     *)
1493                         CASEX=cAsE;;
1494                 esac
1495                 if run_grubfstest cmp "$GRUBDIR/CaSe" "$MNTPOINTRO/$OSDIR/${CASEX}"  ; then
1496                     :
1497                 else
1498                     echo CASE1 READ FAIL
1499                     exit 1
1500                 fi
1501                 if run_grubfstest cmp "$GRUBDIR/cAsE" "$MNTPOINTRO/$OSDIR/CaSe"  ; then
1502                     :
1503                 else
1504                     echo CASE2 READ FAIL
1505                     exit 1
1506                 fi
1507                 if ! cmp "$MNTPOINTRO/$OSDIR/CaSe" "$MNTPOINTRO/$OSDIR/${CASEX}" > /dev/null ; then
1508                     echo CASE CMP READ FAIL
1509                     exit 1
1510                 fi
1511                 if  test x$ok = xtrue; then
1512                     :
1513                 else
1514                     echo CASE READ FAIL
1515                     exit 1
1516                 fi
1517             fi
1518
1519             case x"$fs" in
1520                 x"zfs"*)
1521                     while ! zpool export "$FSLABEL" ; do
1522                         sleep 1;
1523                     done
1524                     sleep 5;;
1525                 x"tarfs" | x"cpio_"* | xrockridge | xjoliet | xrockridge_joliet | x"ziso9660" | x"romfs" | x"squash4_"* | xiso9660 | xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999)
1526                     rm -rf "$MNTPOINTRW";;
1527                 x"afs")
1528                     rm -rf "$MNTPOINTRO"
1529                     ;;
1530                 *)
1531                     sleep 1
1532                     umount "$MNTPOINTRO"  || true
1533                     umount "$MNTPOINTRW" || true
1534             esac
1535             sleep 1
1536             case x"$fs" in
1537                 xmdraid*)
1538                     mdadm --stop /dev/md/"${fs}_$NDEVICES"
1539                     sleep 1
1540                     ;;
1541                 xlvm*)
1542                     vgchange -a n grub_test
1543                     sleep 1
1544                     ;;
1545             esac
1546             case x"$fs" in
1547                 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) ;;
1548                 *)
1549                     for lodev in $LODEVICES; do
1550                         while ! losetup -d "$lodev"; do
1551                             sleep 1
1552                         done
1553                     done;;
1554             esac
1555             for i in $(range 0 $((NDEVICES-1)) 1); do
1556                 rm "$FSIMAGEP${i}.img"
1557             done
1558             if [ x"$fs" = x"zfs" ]; then
1559                 rmdir "$MNTPOINTRW"/"grub fs"  || true
1560                 rmdir "$MNTPOINTRO"/"grub fs"  || true
1561             fi
1562             rm -rf "$MNTPOINTRW"  || true
1563             rm -rf "$MNTPOINTRO"  || true
1564         done
1565     done
1566 done
1567 rmdir "${tempdir}"