mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-11-09 21:30:07 +00:00
2b2d00653c
Unify coding style of shell scripts in accordance with shellcheck errors. Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
212 lines
5.1 KiB
Bash
212 lines
5.1 KiB
Bash
#!/usr/bin/env bash
|
|
: '
|
|
This script checks if an image is compatible with Cloud Hypervisor.
|
|
At first, it detects the image type(raw or qcow2),
|
|
partition type whether it is DOS or GPT.
|
|
Then it mounts the image and checks if VIRTIO Configs
|
|
are enabled in the kernel config. In the end, it provides
|
|
a message about the compatibility of the image.
|
|
'
|
|
|
|
usage="$(basename "$0") [-h] -f -w -- program to check Cloud Hypervisor compatible image
|
|
|
|
where:
|
|
-h show this help text
|
|
-f image file location
|
|
-w directory to be used for temporary files"
|
|
|
|
function check_command {
|
|
if ! command -v "$1" &>/dev/null; then
|
|
echo "Command $1 could not be found"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function check_if_root {
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo "Please run as root"
|
|
exit 1
|
|
fi
|
|
|
|
}
|
|
|
|
check_if_root
|
|
working_dir=""
|
|
while getopts ':hf:w:' option; do
|
|
case "$option" in
|
|
h)
|
|
echo "$usage"
|
|
exit
|
|
;;
|
|
f)
|
|
file_name=$OPTARG
|
|
;;
|
|
w)
|
|
working_dir=$OPTARG
|
|
;;
|
|
:)
|
|
printf "missing argument for -%s\n" "$OPTARG" >&2
|
|
echo "$usage" >&2
|
|
exit 1
|
|
;;
|
|
\?)
|
|
printf "illegal option: -%s\n" "$OPTARG" >&2
|
|
echo "$usage" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
shift $((OPTIND - 1))
|
|
|
|
if [ -z "${file_name}" ]; then
|
|
echo "You must provide the image file name"
|
|
exit 1
|
|
fi
|
|
if [[ ! -f ${file_name} ]]; then
|
|
echo "File ${file_name} does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
file_abs_path=$(readlink -m "${file_name}")
|
|
if [[ "${working_dir}" != "" && ! -d "${working_dir}" ]]; then
|
|
echo "Directory ${working_dir} does not exist"
|
|
exit 1
|
|
elif [[ "${working_dir}" == "" ]]; then
|
|
working_dir=$(mktemp -d)
|
|
tmp_created=1
|
|
else
|
|
working_dir=$(readlink -m "${working_dir}")
|
|
fi
|
|
|
|
filename="${file_name%.*}"
|
|
dest_file=${working_dir}/${filename}.raw
|
|
image_type=$(qemu-img info "${file_abs_path}" | grep 'file format:' | awk '{ print $3 }')
|
|
echo "Image type detected as ${image_type}"
|
|
|
|
if [[ "${image_type}" == "raw" ]]; then
|
|
dest_file=${file_abs_path}
|
|
elif [[ "$image_type" == "qcow2" ]]; then
|
|
if lsmod | grep "nbd" &>/dev/null; then
|
|
echo "Module nbd is loaded!"
|
|
else
|
|
echo "Module nbd is not loaded. Trying to load the module"
|
|
|
|
if ! modprobe nbd max_part=8; then
|
|
echo "failed to load nbd module. Exiting"
|
|
exit 1
|
|
fi
|
|
fi
|
|
check_command qemu-img
|
|
dest_file=/dev/nbd0
|
|
qemu-nbd --connect=${dest_file} "${file_abs_path}" --read-only
|
|
fi
|
|
|
|
check_command blkid
|
|
#get part info
|
|
part_type=$(blkid -o value -s PTTYPE "${dest_file}")
|
|
|
|
check_command partx
|
|
nr_partitions=$(partx -g "${dest_file}" | wc -l)
|
|
|
|
check_command fdisk
|
|
out=$(fdisk -l "${dest_file}" --bytes | grep -i -A "${nr_partitions}" 'Device' | tail -n +2)
|
|
|
|
IFS='
|
|
'
|
|
i=0
|
|
declare -A lines
|
|
for x in $out; do
|
|
lines[$i]=$x
|
|
i=$((i + 1))
|
|
done
|
|
|
|
declare -A partitions
|
|
IFS=' '
|
|
i=0
|
|
ROWS=${#lines[@]}
|
|
|
|
for line in "${lines[@]}"; do
|
|
j=0
|
|
read -a -r str_arr <<<"$line"
|
|
for val in "${str_arr[@]}"; do
|
|
if [[ "$val" != "*" ]]; then
|
|
partitions[$i, $j]=$val
|
|
j=$((j + 1))
|
|
fi
|
|
done
|
|
i=$((i + 1))
|
|
done
|
|
|
|
COLUMNS=$j
|
|
START_ADDRESS_INDEX=1
|
|
FILE_SYS_INDEX2=$((COLUMNS - 1))
|
|
FILE_SYS_INDEX1=$((COLUMNS - 2))
|
|
DEVICE_INDEX=0
|
|
# Here we have all the partition info now lets mount and analyze the contents
|
|
for ((i = 0; i < ROWS; i++)); do
|
|
if [[ "$part_type" == "gpt" && "${partitions[$i, ${FILE_SYS_INDEX1}]}" == "Linux" && "${partitions[$i, ${FILE_SYS_INDEX2}]}" == "filesystem" ]]; then
|
|
echo "The image has GPT partitions"
|
|
MOUNT_ROW=$i
|
|
break
|
|
elif [[ "$part_type" == "dos" && "${partitions[$i, ${FILE_SYS_INDEX1}]}" == "Linux" && "${partitions[$i, ${FILE_SYS_INDEX2}]}" == "" ]]; then
|
|
echo "The image has DOS partitions"
|
|
MOUNT_ROW=$i
|
|
break
|
|
fi
|
|
done
|
|
|
|
start_address=${partitions[${MOUNT_ROW}, ${START_ADDRESS_INDEX}]}
|
|
offset=$((start_address * 512))
|
|
|
|
MOUNT_DIR=/mnt/clh-img-check/
|
|
rm -rf ${MOUNT_DIR}
|
|
mkdir ${MOUNT_DIR}
|
|
if [[ "${image_type}" == "raw" ]]; then
|
|
mount -o ro,loop,offset=$offset "${dest_file}" ${MOUNT_DIR}
|
|
elif [[ "${image_type}" == "qcow2" ]]; then
|
|
mount -o ro "${partitions[${MOUNT_ROW}, ${DEVICE_INDEX}]}" ${MOUNT_DIR}
|
|
fi
|
|
|
|
CONFIG_DIR=${MOUNT_DIR}boot/
|
|
if [[ "$part_type" == "dos" ]]; then
|
|
CONFIG_DIR=${MOUNT_DIR}
|
|
fi
|
|
|
|
#check VIRTIO
|
|
HAS_VIRTIO=1
|
|
for conf_file in "${CONFIG_DIR}"config*; do
|
|
out=$(grep -cE "CONFIG_VIRTIO=y|CONFIG_VIRTIO_BLK=y|CONFIG_VIRTIO_BLK=m" "${conf_file}")
|
|
if [[ "$out" != "2" ]]; then
|
|
echo "VIRTIO not found"
|
|
HAS_VIRTIO=0
|
|
fi
|
|
done
|
|
|
|
#clean up
|
|
umount ${MOUNT_DIR}
|
|
|
|
if [[ "${tmp_created}" == "1" ]]; then
|
|
rm -rf "${working_dir}"
|
|
fi
|
|
|
|
if [[ "${image_type}" == "qcow2" ]]; then
|
|
qemu-nbd --disconnect "${dest_file}" >/dev/null
|
|
fi
|
|
|
|
result=""
|
|
if [[ "${part_type}" == "dos" ]]; then
|
|
result="dos mode not supported"
|
|
fi
|
|
if [[ "${HAS_VIRTIO}" == "0" ]]; then
|
|
if [[ "$result" != "" ]]; then
|
|
result="${result},"
|
|
fi
|
|
result="$result VirtIO module not found in the image"
|
|
fi
|
|
if [[ "$result" == "" ]]; then
|
|
echo "No incompatibilities found"
|
|
else
|
|
echo "$result"
|
|
fi
|