diff --git a/src/datastore_mad/remotes/fs/snap_flatten b/src/datastore_mad/remotes/fs/snap_flatten index 262336989d..d7baa0e253 100755 --- a/src/datastore_mad/remotes/fs/snap_flatten +++ b/src/datastore_mad/remotes/fs/snap_flatten @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -ex # -------------------------------------------------------------------------- # # Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs # @@ -62,7 +62,7 @@ SNAP_PATH="${SNAP_DIR}/${SNAP_ID}" SNAP_PATH_RELATIVE=$(basename ${SNAP_PATH}) CURRENT_PATH=${DISK_PATH} -rm ${DISK_PATH} -qemu-img convert -O qcow2 ${SNAP_PATH} ${CURRENT_PATH} +qemu-img convert -O qcow2 ${SNAP_PATH} ${CURRENT_PATH}.tmp +mv "${CURRENT_PATH}.tmp" "${CURRENT_PATH}" rm -rf ${SNAP_DIR} diff --git a/src/tm_mad/qcow2/clone b/src/tm_mad/qcow2/clone index bbce31ac90..6ba3bd8ed6 100755 --- a/src/tm_mad/qcow2/clone +++ b/src/tm_mad/qcow2/clone @@ -96,9 +96,11 @@ http://*) RESIZE_CMD="; qemu-img resize ${DST_PATH} ${SIZE}M" fi - CLONE_CMD="cd $DST_DIR; \ - rm -f $DST_PATH; $QEMU_IMG create -b $SRC_PATH -f qcow2 $DST_PATH \ + CLONE_CMD="cd $DST_DIR; rm -f $DST_PATH; \ + $QEMU_IMG create -b $SRC_PATH -f qcow2 ${DST_PATH}.orig; \ + ln -s ${DST_PATH}.orig ${DST_PATH}; \ ${RESIZE_CMD}" + ssh_exec_and_log "$DST_HOST" "$CLONE_CMD" "Error copying $SRC to $DST" ;; esac diff --git a/src/tm_mad/qcow2/snap_create b/src/tm_mad/qcow2/snap_create index b5f0f595e9..f2bc71f5de 100755 --- a/src/tm_mad/qcow2/snap_create +++ b/src/tm_mad/qcow2/snap_create @@ -52,27 +52,89 @@ while IFS= read -r -d '' element; do XPATH_ELEMENTS[i++]="$element" done < <(onevm show -x $VMID| $XPATH \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SOURCE \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE) + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TARGET \ + "/VM/SNAPSHOTS[DISK_ID=$DISK_ID]/SNAPSHOT[last()]/ID" \ + /VM/HISTORY_RECORDS/HISTORY/VMMMAD \ + /VM/STATE \ + /VM/LCM_STATE \ + '%m%/VM/TEMPLATE/DISK/TARGET') DISK_SRC="${XPATH_ELEMENTS[j++]}" CLONE="${XPATH_ELEMENTS[j++]}" +TARGET="${XPATH_ELEMENTS[j++]}" +LAST_SNAP_ID="${XPATH_ELEMENTS[j++]}" +VMMAD="${XPATH_ELEMENTS[j++]}" +STATE="${XPATH_ELEMENTS[j++]}" +LCM_STATE="${XPATH_ELEMENTS[j++]}" +ALL_DISKS="${XPATH_ELEMENTS[j++]}" + +if [ -z "$LAST_SNAP_ID" ]; then + LAST_SNAP_ID=0 +fi SYSTEM_DS_PATH=$(dirname ${SRC_PATH}) IMAGE_DS_PATH=$(dirname ${DISK_SRC}) +SYSTEM_DS_DISK_PATH="${SYSTEM_DS_PATH}/disk.${DISK_ID}" if [ "$CLONE" = "YES" ]; then - DISK_PATH="${SYSTEM_DS_PATH}/disk.${DISK_ID}" + DISK_PATH="${SYSTEM_DS_DISK_PATH}" + DISK_PATH_ORIG="${DISK_PATH}.orig" else DISK_PATH=$DISK_SRC + DISK_PATH_ORIG=$DISK_PATH fi +SNAP_ID=$(( $LAST_SNAP_ID + 1 )) + SNAP_DIR="${DISK_PATH}.snap" SNAP_PATH="${SNAP_DIR}/${SNAP_ID}" +LAST_SNAP_PATH="${SNAP_DIR}/${LAST_SNAP_ID}" SNAP_PATH_RELATIVE=$(basename ${SNAP_PATH}) CURRENT_PATH=${DISK_PATH} +# virsh snapshot-create by default creates snapshots for all the disks that +# are not read only. To be able to make a snapshot in only one of the disks +# an xml must be created describing all of the disks and setting the value +# snapshot='no' to the disks that are not going to be snapshotted. + +# +# 1 +# snap 1 +# +# +# +# +# +# +# +# + + +DOC=" + + ${SNAP_ID} + snap ${SNAP_ID} + " + +for disk in $ALL_DISKS; do + if [ "$disk" = "$TARGET" ]; then + DOC="$DOC + + + " + else + DOC="$DOC + " + fi +done + +DOC="$DOC + +" + CMD=$(cat < \$FILENAME -# Convert backing file absolute path to relative path so it works outside -# the system directory. Do not do this for snapshot one as: -# * It could be a non backed file (persistent) -# * The backing file is in images directory, is not relative -if [ "$SNAP_ID" != "0" ]; then - BACKING_FILE=\$(qemu-img info ${SNAP_PATH} | grep '^backing file:' | \ - cut -d: -f2 | sed 's/^ //') + virsh -c qemu:///system snapshot-create one-$VMID --disk-only --atomic \ + --xmlfile \$FILENAME --quiesce - if [ -n "\$BACKING_FILE" ]; then - RELATIVE_BACKING_FILE="\$(basename \${BACKING_FILE})" + ln -sf $SNAP_PATH $SYSTEM_DS_DISK_PATH - qemu-img rebase -u -b "\${RELATIVE_BACKING_FILE}" "${SNAP_PATH}" + rm \$FILENAME +else + if [ "$SNAP_ID" = "1" ]; then + ORIG="$DISK_PATH_ORIG" + else + ORIG="$LAST_SNAP_PATH" fi + + qemu-img create -f qcow2 -b "\${ORIG}" "${SNAP_PATH}" + ln -sf $SNAP_PATH $SYSTEM_DS_DISK_PATH +fi + +if [ "$SNAP_ID" = "1" ] && [ "$CLONE" != "YES" ]; then + ln -sf "${DISK_PATH_ORIG}" "${SNAP_DIR}/0" +fi + +BACKING_FILE=\$(qemu-img info ${SNAP_PATH} | grep '^backing file:' | \ + cut -d: -f2 | sed 's/^ //') + +if [ "\${BACKING_FILE}" = "${SYSTEM_DS_DISK_PATH}" ]; then + REAL_BACKING_FILE="${DISK_PATH_ORIG}" + qemu-img rebase -u -b "\${REAL_BACKING_FILE}" "${SNAP_PATH}" fi EOT ) diff --git a/src/tm_mad/qcow2/snap_revert b/src/tm_mad/qcow2/snap_revert index 8aa19a0ba0..3218e83134 100755 --- a/src/tm_mad/qcow2/snap_revert +++ b/src/tm_mad/qcow2/snap_revert @@ -67,13 +67,16 @@ else DISK_PATH=$DISK_SRC fi +NEXT_ID=$(( $SNAP_ID + 1 )) SNAP_DIR="${DISK_PATH}.snap" SNAP_PATH="${SNAP_DIR}/${SNAP_ID}" +SNAP_PATH_NEXT="${SNAP_DIR}/${NEXT_ID}" SNAP_PATH_RELATIVE=$(basename ${SNAP_PATH}) CURRENT_PATH=${DISK_PATH} -CMD="rm \"${CURRENT_PATH}\" ; \ -qemu-img create -f qcow2 -b \"${SNAP_PATH}\" \"${CURRENT_PATH}\"" +CMD="set -ex ; \ +qemu-img create -f qcow2 -b \"${SNAP_PATH}\" \"${CURRENT_PATH}\"; \ +" ssh_exec_and_log "${SRC_HOST}" "${CMD}" \ "Error reverting snapshot to ${SNAP_PATH}" diff --git a/src/tm_mad/shared/ln b/src/tm_mad/shared/ln index d73a5f8f18..baf5a21d80 100755 --- a/src/tm_mad/shared/ln +++ b/src/tm_mad/shared/ln @@ -63,8 +63,21 @@ ssh_make_path $DST_HOST $DST_DIR #------------------------------------------------------------------------------- log "Linking $SRC_PATH in $DST" -ssh_exec_and_log $DST_HOST \ - "cd $DST_DIR; rm -f $DST_PATH ; ln -s $SRC_PATH $DST_PATH" \ - "Error linking $SRC to $DST" +CMD=$(cat <