From: Kirill Tkhai <kirill.tkhai@openvz.org>
To: agk@redhat.com, snitzer@redhat.com, dm-devel@redhat.com,
song@kernel.org, linux-kernel@vger.kernel.org,
khorenko@virtuozzo.com, kirill.tkhai@openvz.org
Subject: [PATCH 4/4] dm-qcow2: Add helper for working with dm-qcow2 devices
Date: Mon, 28 Mar 2022 14:18:41 +0300 [thread overview]
Message-ID: <164846632180.251310.3616379476259718920.stgit@pro> (raw)
In-Reply-To: <164846619932.251310.3668540533992131988.stgit@pro>
This scripts allows to create and remove dm-qcow2 device,
create internal snapshot, resize virtual device size,
or check image consistency on live device.
Signed-off-by: Kirill Tkhai <kirill.tkhai@openvz.org>
---
scripts/qcow2-dm.sh | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 249 insertions(+)
create mode 100755 scripts/qcow2-dm.sh
diff --git a/scripts/qcow2-dm.sh b/scripts/qcow2-dm.sh
new file mode 100755
index 000000000000..7d9bda44c1d6
--- /dev/null
+++ b/scripts/qcow2-dm.sh
@@ -0,0 +1,249 @@
+#!/bin/bash
+#
+# This requires parameter dm_qcow2.kernel_sets_dirty_bit=y
+
+usage () {
+ cat <<EOF
+Usage:
+ $prog_name create <file.qcow2> <dev_name>
+ $prog_name remove <file.qcow2>
+ $prog_name check [qemu-img check optional args] <file.qcow2>
+ $prog_name snapshot [qemu-img snapshot optional args] <file.qcow2>
+ $prog_name resize [qemu-img resize optional args] <file.qcow2> [+ | -]size
+EOF
+}
+
+get_img_size () {
+ sz=`qemu-img info -f qcow2 $1 | grep "virtual size" | sed 's/.*(\(.*\) bytes)/\1/'`
+ echo $sz
+}
+
+get_nr_imgs () {
+ nr=`echo $1 | sed "s/.*qcow2 \(\w\) .*$/\1/"`
+ echo $nr
+}
+
+get_dev_of_image () {
+ abs_path=$1
+
+ while read line; do
+ dev=`echo $line | sed "s/:.*//"`
+ nr_imgs=$(get_nr_imgs "$line")
+ top_img_id=$((nr_imgs - 1))
+
+ top_img_path=`dmsetup message $dev 0 get_img_name $top_img_id`
+ if [ -z "$top_img_path" ]; then
+ echo >&2 "Error during search of device"; exit 1;
+ return 1
+ fi
+
+ if [ "$abs_path" != "$top_img_path" ]; then
+ continue
+ fi
+
+ echo $dev
+ return 0
+
+ done < <(LANG=C dmsetup table --target=qcow2 | grep -v "No devices found")
+
+ return 0
+}
+
+create () {
+ if [ "$#" -ne 2 ]; then
+ echo >&2 "Wrong number of arguments."; usage; exit 1;
+ fi
+
+ file=$1
+ dev=$2
+ files=()
+ fds=""
+
+ qemu-img check $file || exit 1
+
+ disk_sz=$(get_img_size "$file")
+ echo disk_sz=$disk_sz
+ if [ -z "$disk_sz" ]; then
+ echo "Can't get disk size."; exit 1;
+ fi
+
+ while :; do
+ if [ ! -f "$file" ]; then
+ echo "$file does not exist."; exit 1;
+ fi
+
+ files+=("$file")
+
+ exec {fd}<>$file || exit 1
+ flock -x $fd || exit 1
+ fds="$fd $fds"
+
+ file=`qemu-img info $file | grep "backing file:" | sed "s/backing file: //"`
+ if [ -z "$file" ]; then
+ break
+ fi
+ done
+
+ echo "Create device [$dev] of size $disk_sz from [${files[*]}]."
+ dmsetup create $dev --table "0 $((disk_sz / 512)) qcow2 ${fds}"
+}
+
+reload_device () {
+ disk_sz=$(get_img_size "$abs_path")
+ if [ -z "$disk_sz" ]; then
+ echo "Can't get disk size."; return;
+ fi
+
+ line=`dmsetup table $dev`
+ nr_imgs=$(get_nr_imgs "$line")
+ top_img_id=$((nr_imgs - 1))
+ fds=""
+
+ for id in `seq 0 $top_img_id`;
+ do
+ file=`dmsetup message $dev 0 get_img_name $id`
+ if [ -z "$file" ]; then
+ echo "Can't get image file."; return;
+ fi
+ exec {fd}<>$file || exit 1
+
+ fds="$fds $fd"
+ done
+
+ echo "Reloading $dev."
+ dmsetup reload $dev --table "0 $((disk_sz / 512)) qcow2 ${fds}"
+}
+
+remove () {
+ if [ "$#" -ne 1 ]; then
+ echo >&2 "Wrong number of arguments."; usage; exit 1;
+ fi
+ user_path=$1
+ abs_path=`realpath $user_path`
+
+ dev=$(get_dev_of_image "$abs_path")
+ if [ -z "$dev" ]; then
+ echo >&2 "Can't find device with [$user_path] top image."; exit 1
+ fi
+
+ echo "Removing device [$dev]."
+ dmsetup remove $dev
+ ret=$?
+
+ if [ $ret -eq 0 ]; then
+ #Sanity check
+ echo "Checking [$abs_path]."
+ qemu-img check $abs_path
+ fi
+ exit $ret
+}
+
+qemu_img () {
+ wants_reload=0
+ if [ $1 == "--wants_reload" ]; then
+ wants_reload=1
+ shift
+ fi
+
+ if [ "$#" -lt 3 ]; then
+ echo >&2 "Wrong number of arguments."; usage; exit 1;
+ fi
+
+ user_path=$1
+ cmd=$2
+ abs_path=`realpath $user_path`
+ qemu_img_args=${@: 2}
+
+ dev=$(get_dev_of_image "$abs_path")
+ if [ -z "$dev" ]; then
+ echo >&2 "Can't find device by [$user_path]."; return 1
+ fi
+
+ echo "Suspending $dev."
+ dmsetup suspend $dev || exit 1
+
+ if [ "$cmd" != "check" ]; then
+ echo "Checking $abs_path"
+ qemu-img check $abs_path
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ echo "Resuming $dev."
+ dmsetup resume $dev
+ exit 1
+ fi
+ fi
+
+ echo "===== Call: qemu-img $qemu_img_args. ====="
+ qemu-img $qemu_img_args
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ echo >&2 "Failed during qemu-img call."
+ fi
+ echo "===== End of qemu-img $qemu_img_args. ====="
+
+ if [ $wants_reload -ne 0 ]; then
+ reload_device $dev $abs_path
+ fi
+
+ echo "Resuming $dev."
+ dmsetup resume $dev || exit 1
+ if [ $? -ne 0 ]; then
+ ret=$?
+ fi
+
+ return $ret
+}
+
+check () {
+ user_path=${@: -1}
+ qemu_img_args=$@
+
+ qemu_img $user_path check $qemu_img_args
+ return $?
+}
+
+snapshot () {
+ user_path=${@: -1}
+ qemu_img_args=$@
+
+ qemu_img $user_path snapshot $qemu_img_args
+ return $?
+}
+
+resize () {
+ user_path=${@:(-2):1}
+ qemu_img_args=$@
+
+ qemu_img --wants_reload $user_path resize $qemu_img_args
+ return $?
+}
+
+prog_name=$(basename $0)
+
+case $1 in
+ "create")
+ shift
+ create "$@"
+ exit 0
+ ;;
+ "remove")
+ shift
+ remove "$@"
+ ;;
+ "check")
+ shift
+ check "$@"
+ ;;
+ "snapshot")
+ shift
+ snapshot "$@"
+ ;;
+ "resize")
+ shift
+ resize "$@"
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+esac
next prev parent reply other threads:[~2022-03-28 11:19 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-28 11:18 [PATCH 0/4] dm: Introduce dm-qcow2 driver to attach QCOW2 files as block device Kirill Tkhai
2022-03-28 11:18 ` [PATCH 1/4] dm: Export dm_complete_request() Kirill Tkhai
2022-03-28 11:18 ` [PATCH 2/4] dm: Process .io_hints for drivers not having underlying devices Kirill Tkhai
2022-03-28 11:18 ` [PATCH 3/4] dm-qcow2: Introduce driver to create block devices over QCOW2 files Kirill Tkhai
2022-03-28 20:03 ` kernel test robot
2022-03-28 23:42 ` kernel test robot
2022-03-29 10:42 ` [PATCH 3/4 v1.5] " Kirill Tkhai
2022-03-29 13:34 ` [dm-devel] [PATCH 3/4] " Christoph Hellwig
2022-03-29 15:24 ` Kirill Tkhai
2022-03-29 22:30 ` Kirill Tkhai
2022-03-28 11:18 ` Kirill Tkhai [this message]
2022-03-29 13:08 ` [dm-devel] [PATCH 0/4] dm: Introduce dm-qcow2 driver to attach QCOW2 files as block device Christoph Hellwig
2022-03-29 15:14 ` Kirill Tkhai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=164846632180.251310.3616379476259718920.stgit@pro \
--to=kirill.tkhai@openvz.org \
--cc=agk@redhat.com \
--cc=dm-devel@redhat.com \
--cc=khorenko@virtuozzo.com \
--cc=linux-kernel@vger.kernel.org \
--cc=snitzer@redhat.com \
--cc=song@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox