@@ -36,18 +36,26 @@ info()
3636 echo " INFO: ${msg} "
3737}
3838
39+ warning ()
40+ {
41+ local msg=" $* "
42+ echo " WARNING: ${msg} "
43+ }
44+
3945usage ()
4046{
4147 error=" ${1:- 0} "
4248 cat << EOT
4349Usage: ${SCRIPT_NAME} [options] <rootfs-dir>
44- This script will create a Kata Containers image file based on the
45- <rootfs-dir> directory.
50+ This script will create a Kata Containers image file of
51+ an adequate size based on the <rootfs-dir> directory.
52+ The size of the image can be also be specified manually
53+ by '-s' flag.
4654
4755Options:
4856 -h Show this help
4957 -o path to generate image file ENV: IMAGE
50- -s Image size in MB (default $IMG_SIZE ) ENV: IMG_SIZE
58+ -s Image size in MB ENV: IMG_SIZE
5159
5260Extra environment variables:
5361 AGENT_BIN: use it to change the expected agent binary name"
5765exit " ${error} "
5866}
5967
60- while getopts " ho:s:" opt
68+ # Maximum allowed size in MB for root disk
69+ MAX_IMG_SIZE_MB=2048
70+
71+ FS_TYPE=${FS_TYPE:- " ext4" }
72+
73+ # In order to support memory hotplug, image must be aligned to 128M
74+ MEM_BOUNDARY=128
75+
76+ # Maximum no of attempts to create a root disk before giving up
77+ MAX_ATTEMPTS=5
78+
79+ ATTEMPT_NUM=0
80+ while getopts " ho:s:f:" opt
6181do
6282 case " $opt " in
6383 h) usage ;;
6484 o) IMAGE=" ${OPTARG} " ;;
65- s) IMG_SIZE=" ${OPTARG} " ;;
85+ s) IMG_SIZE=${OPTARG}
86+ if [ ${IMG_SIZE} -lt 0 ]; then
87+ die " Image size has to be greater than 0 MB."
88+ fi
89+ if [ ${IMG_SIZE} -gt ${MAX_IMG_SIZE_MB} ]; then
90+ die " Image size should not be greater than ${MAX_IMG_SIZE_MB} MB."
91+ fi
92+ ;;
93+ f) FS_TYPE=" ${OPTARG} " ;;
6694 esac
6795done
6896
@@ -113,55 +141,104 @@ OK "init is installed"
113141OK " Agent installed"
114142[ " $( id -u) " -eq 0 ] || die " $0 : must be run as root"
115143
144+ ROOTFS_SIZE=$( du -B 1MB -s " ${ROOTFS} " | awk ' {print $1}' )
116145BLOCK_SIZE=${BLOCK_SIZE:- 4096}
117- IMG_SIZE=${IMG_SIZE:- 80}
118-
119- info " Creating raw disk with size ${IMG_SIZE} M"
120- qemu-img create -q -f raw " ${IMAGE} " " ${IMG_SIZE} M"
121- OK " Image file created"
146+ OLD_IMG_SIZE=0
122147
123- # Kata runtime expect an image with just one partition
124- # The partition is the rootfs content
125-
126- info " Creating partitions"
127- parted " ${IMAGE} " --script " mklabel gpt" \
128- " mkpart ext4 1M -1M"
129- OK " Partitions created"
130-
131- # Get the loop device bound to the image file (requires /dev mounted in the
132- # image build system and root privileges)
133- DEVICE=$( losetup -P -f --show " ${IMAGE} " )
148+ align_memory ()
149+ {
150+ remaining=$(( $IMG_SIZE % $MEM_BOUNDARY ))
151+ if [ " $remaining " != " 0" ]; then
152+ warning " image size '$IMG_SIZE ' is not aligned to memory boundary '$MEM_BOUNDARY ', aligning it"
153+ IMG_SIZE=$(( $IMG_SIZE + $MEM_BOUNDARY - $remaining ))
154+ fi
155+ }
134156
135- # Refresh partition table
136- partprobe " ${DEVICE} "
157+ # Calculate image size based on the rootfs
158+ calculate_img_size ()
159+ {
160+ IMG_SIZE=${IMG_SIZE:- $MEM_BOUNDARY }
161+ align_memory
162+ }
137163
138- MOUNT_DIR=$( mktemp -d osbuilder-mount-dir.XXXX)
139- info " Formating Image using ext4 format"
140- mkfs.ext4 -q -F -b " ${BLOCK_SIZE} " " ${DEVICE} p1"
141- OK " Image formated"
164+ # Cleanup
165+ cleanup ()
166+ {
167+ sync
168+ umount -l ${MOUNT_DIR}
169+ rmdir ${MOUNT_DIR}
170+ fsck -D -y " ${DEVICE} p1"
171+ losetup -d " ${DEVICE} "
172+ }
142173
143- info " Mounting root paratition"
144- mount " ${DEVICE} p1" " ${MOUNT_DIR} "
145- OK " root paratition mounted"
174+ create_rootfs_disk ()
175+ {
176+ ATTEMPT_NUM=$(( $ATTEMPT_NUM + 1 ))
177+ info " Create root disk image. Attempt ${ATTEMPT_NUM} out of ${MAX_ATTEMPTS} ."
178+ if [ ${ATTEMPT_NUM} -gt ${MAX_ATTEMPTS} ]; then
179+ die " Unable to create root disk image."
180+ fi
181+
182+ calculate_img_size
183+ if [ ${OLD_IMG_SIZE} -ne 0 ]; then
184+ info " Image size ${OLD_IMG_SIZE} MB too small, trying again with size ${IMG_SIZE} MB"
185+ fi
186+
187+ info " Creating raw disk with size ${IMG_SIZE} M"
188+ qemu-img create -q -f raw " ${IMAGE} " " ${IMG_SIZE} M"
189+ OK " Image file created"
190+
191+ # Kata runtime expect an image with just one partition
192+ # The partition is the rootfs content
193+
194+ info " Creating partitions"
195+ parted " ${IMAGE} " --script " mklabel gpt" \
196+ " mkpart ${FS_TYPE} 1M -1M"
197+ OK " Partitions created"
198+
199+ # Get the loop device bound to the image file (requires /dev mounted in the
200+ # image build system and root privileges)
201+ DEVICE=$( losetup -P -f --show " ${IMAGE} " )
202+
203+ # Refresh partition table
204+ partprobe " ${DEVICE} "
205+
206+ MOUNT_DIR=$( mktemp -d osbuilder-mount-dir.XXXX)
207+ info " Formating Image using ext4 format"
208+ mkfs.ext4 -q -F -b " ${BLOCK_SIZE} " " ${DEVICE} p1"
209+ OK " Image formated"
210+
211+ info " Mounting root paratition"
212+ mount " ${DEVICE} p1" " ${MOUNT_DIR} "
213+ OK " root paratition mounted"
214+ RESERVED_BLOCKS_PERCENTAGE=3
215+ info " Set filesystem reserved blocks percentage to ${RESERVED_BLOCKS_PERCENTAGE} %"
216+ tune2fs -m " ${RESERVED_BLOCKS_PERCENTAGE} " " ${DEVICE} p1"
217+
218+ AVAIL_DISK=$( df -B M --output=avail " ${DEVICE} p1" | tail -1)
219+ AVAIL_DISK=${AVAIL_DISK/ M}
220+ info " Free space root partition ${AVAIL_DISK} MB"
221+
222+ # if the available disk space is less than rootfs size, repeat the process
223+ # of disk creation by adding 5% in the inital assumed value $ROOTFS_SIZE
224+ if [ $ROOTFS_SIZE -gt $AVAIL_DISK ]; then
225+ # Increase the size but remain aligned to 128
226+ MEM_BOUNDARY=$(( $MEM_BOUNDARY + 128 ))
227+ rm -f ${IMAGE}
228+ OLD_IMG_SIZE=${IMG_SIZE}
229+ unset IMG_SIZE
230+ cleanup
231+ create_rootfs_disk
232+ fi
233+ }
146234
147- RESERVED_BLOCKS_PERCENTAGE=3
148- info " Set filesystem reserved blocks percentage to ${RESERVED_BLOCKS_PERCENTAGE} %"
149- tune2fs -m " ${RESERVED_BLOCKS_PERCENTAGE} " " ${DEVICE} p1"
235+ create_rootfs_disk
150236
151- # TODO: Calculate disk size based on rootfs
152- # FIXME: https://github.com/kata-containers/osbuilder/issues/2
153- ROOTFS_SIZE=$( du -B 1MB -s " ${ROOTFS} " | awk ' {print $1}' )
154- AVAIL_DISK=$( df -B M --output=avail " ${DEVICE} p1" | tail -1)
155- AVAIL_DISK=${AVAIL_DISK/ M}
156- info " Free space root partition ${AVAIL_DISK} MB"
157237info " rootfs size ${ROOTFS_SIZE} MB"
158238info " Copying content from rootfs to root partition"
159239cp -a " ${ROOTFS} " /* ${MOUNT_DIR}
160240OK " rootfs copied"
161241
162- # Cleanup
163- sync
164- umount -l ${MOUNT_DIR}
165- fsck -D -y " ${DEVICE} p1"
166- losetup -d " ${DEVICE} "
167- info " Image created"
242+ cleanup
243+
244+ info " Image created. Size: ${IMG_SIZE} MB."
0 commit comments