blob: 0f0c38463991e4d6820c3625669da2524dccb484 [file] [log] [blame]
Alex Deymo2b19cfb2015-03-26 00:35:07 -07001#!/bin/bash
2
3# Copyright 2015 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7set -e
8
9# cleanup <path>
10# Unmount and remove the mountpoint <path>
11cleanup() {
12 if ! sudo umount "$1" 2>/dev/null; then
13 if mountpoint -q "$1"; then
14 sync && sudo umount "$1"
15 fi
16 fi
17 rmdir "$1"
18}
19
20# generate_fs <filename> <size> [block_size] [block_groups]
21generate_fs() {
22 local filename="$1"
23 local size="$2"
24 local block_size="${3:-4096}"
25 local block_groups="${4:-}"
26
27 local mkfs_opts=( -q -F -b "${block_size}" -L "ROOT-TEST" -t ext2 )
28 if [[ -n "${block_groups}" ]]; then
29 mkfs_opts+=( -G "${block_groups}" )
30 fi
31
32 local mntdir=$(mktemp --tmpdir -d generate_ext2.XXXXXX)
33 trap 'cleanup "${mntdir}"; rm -f "${filename}"' INT TERM EXIT
34
35 # Cleanup old image.
36 if [[ -e "${filename}" ]]; then
37 rm -f "${filename}"
38 fi
39 truncate --size="${size}" "${filename}"
40
41 mkfs.ext2 "${mkfs_opts[@]}" "${filename}"
42 sudo mount "${filename}" "${mntdir}" -o loop
43
44 ### Generate the files used in unittest with descriptive names.
45 sudo touch "${mntdir}"/empty-file
46
47 # regular: Regular files.
48 echo "small file" | sudo dd of="${mntdir}"/regular-small status=none
49 dd if=/dev/zero bs=1024 count=16 status=none | tr '\0' '\141' |
50 sudo dd of="${mntdir}"/regular-16k status=none
51 sudo dd if=/dev/zero of="${mntdir}"/regular-32k-zeros bs=1024 count=16 \
52 status=none
53
54 echo "with net_cap" | sudo dd of="${mntdir}"/regular-with_net_cap status=none
55 sudo setcap cap_net_raw=ep "${mntdir}"/regular-with_net_cap
56
57 # sparse_empty: Files with no data blocks at all (only sparse holes).
58 sudo truncate --size=10240 "${mntdir}"/sparse_empty-10k
59 sudo truncate --size=$(( block_size * 2 )) "${mntdir}"/sparse_empty-2blocks
60
61 # sparse: Files with some data blocks but also sparse holes.
62 echo -n "foo" |
63 sudo dd of="${mntdir}"/sparse-16k-last_block bs=1 \
64 seek=$(( 16 * 1024 - 3)) status=none
65
66 # ext2 inodes have 12 direct blocks, one indirect, one double indirect and
67 # one triple indirect. 10000 should be enough to have an indirect and double
68 # indirect block.
69 echo -n "foo" |
70 sudo dd of="${mntdir}"/sparse-10000blocks bs=1 \
71 seek=$(( block_size * 10000 )) status=none
72
73 sudo truncate --size=16384 "${mntdir}"/sparse-16k-first_block
74 echo "first block" | sudo dd of="${mntdir}"/sparse-16k-first_block status=none
75
76 sudo truncate --size=16384 "${mntdir}"/sparse-16k-holes
77 echo "a" | sudo dd of="${mntdir}"/sparse-16k-holes bs=1 seek=100 status=none
78 echo "b" | sudo dd of="${mntdir}"/sparse-16k-holes bs=1 seek=10000 status=none
79
80 # link: symlinks and hardlinks.
81 sudo ln -s "broken-link" "${mntdir}"/link-short_symlink
82 sudo ln -s $(dd if=/dev/zero bs=256 count=1 status=none | tr '\0' '\141') \
83 "${mntdir}"/link-long_symlink
84 sudo ln "${mntdir}"/regular-16k "${mntdir}"/link-hard-regular-16k
85
86 # Directories.
87 sudo mkdir -p "${mntdir}"/dir1/dir2/dir1
88 echo "foo" | sudo tee "${mntdir}"/dir1/dir2/file >/dev/null
89 echo "bar" | sudo tee "${mntdir}"/dir1/file >/dev/null
90
91 # removed: removed files that should not be listed.
92 echo "We will remove this file so it's contents will be somewhere in the " \
93 "empty space data but it won't be all zeros." |
94 sudo dd of="${mntdir}"/removed conv=fsync status=none
95 sudo rm "${mntdir}"/removed
96
97 cleanup "${mntdir}"
98 trap - INT TERM EXIT
99}
100
101image_desc="${1:-}"
102output_dir="${2:-}"
103
104if [[ ! -e "${image_desc}" || ! -d "${output_dir}" ]]; then
105 echo "Use: $0 <image_description.txt> <output_dir>" >&2
106 exit 1
107fi
108
109args=( $(cat ${image_desc}) )
110dest_image="${output_dir}/$(basename ${image_desc} .txt).img"
111generate_fs "${dest_image}" "${args[@]}"