2011-06-08 03:41:22 +02:00
|
|
|
#!/bin/bash
|
2014-01-21 04:40:22 +01:00
|
|
|
|
|
|
|
set -o pipefail
|
|
|
|
|
2010-07-14 18:50:48 +02:00
|
|
|
get_encoded_script()
|
|
|
|
{
|
2014-01-21 04:40:22 +01:00
|
|
|
ENCODED_SCRIPT=`
|
|
|
|
if [ "$1" == "vm-default" ]; then
|
|
|
|
echo /usr/lib/qubes/dispvm-prerun.sh
|
|
|
|
else
|
|
|
|
cat "$1"
|
|
|
|
fi | base64 -w0` || exit 1
|
2010-07-14 18:50:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if [ $# != 2 -a $# != 3 ] ; then
|
2014-11-10 11:42:47 +01:00
|
|
|
echo "usage: $0 domainname savefile_to_be_created [preload script]" >&2
|
2010-06-02 15:50:22 +02:00
|
|
|
exit 1
|
|
|
|
fi
|
2010-06-30 15:23:44 +02:00
|
|
|
export PATH=$PATH:/sbin:/usr/sbin
|
2010-07-14 18:50:48 +02:00
|
|
|
if [ $# = 3 ] ; then
|
|
|
|
get_encoded_script $3
|
|
|
|
fi
|
2010-06-02 15:50:22 +02:00
|
|
|
VMDIR=/var/lib/qubes/appvms/$1
|
|
|
|
if ! [ -d $VMDIR ] ; then
|
2014-11-10 11:42:47 +01:00
|
|
|
echo "$VMDIR does not exist ?" >&2
|
2010-06-02 15:50:22 +02:00
|
|
|
exit 1
|
|
|
|
fi
|
2014-01-24 06:42:20 +01:00
|
|
|
if ! qvm-start $1 --dvm ; then
|
2010-06-02 15:50:22 +02:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2015-03-02 03:35:15 +01:00
|
|
|
ID=`virsh -c xen:/// domid $1`
|
2013-06-10 04:28:13 +02:00
|
|
|
echo "Waiting for DVM $1 ..." >&2
|
2010-07-14 18:50:48 +02:00
|
|
|
if [ -n "$ENCODED_SCRIPT" ] ; then
|
2013-06-10 04:28:13 +02:00
|
|
|
qubesdb-write -d $1 /qubes-save-script "$ENCODED_SCRIPT"
|
2010-07-14 18:50:48 +02:00
|
|
|
fi
|
2010-09-22 11:15:22 +02:00
|
|
|
#set -x
|
2013-06-10 04:28:13 +02:00
|
|
|
qubesdb-write -d $1 /qubes-save-request 1
|
|
|
|
qubesdb-watch -d $1 /qubes-used-mem
|
|
|
|
qubesdb-read -d $1 /qubes-gateway | \
|
2013-03-14 14:45:45 +01:00
|
|
|
cut -d . -f 3 | tr -d "\n" > $VMDIR/netvm-id.txt
|
2015-03-02 03:35:15 +01:00
|
|
|
kill `cat /var/run/qubes/guid-running.$ID`
|
2013-05-04 04:50:37 +02:00
|
|
|
# FIXME: get connection URI from core scripts
|
|
|
|
virsh -c xen:/// detach-disk $1 xvdb
|
2015-05-11 16:49:27 +02:00
|
|
|
MEM=$(qubesdb-read -d $1 /qubes-used-mem | grep '^[0-9]\+$' | head -n 1)
|
2014-11-10 11:42:47 +01:00
|
|
|
echo "DVM boot complete, memory used=$MEM. Saving image..." >&2
|
2010-09-07 16:00:14 +02:00
|
|
|
QMEMMAN_STOP=/var/run/qubes/do-not-membalance
|
|
|
|
touch $QMEMMAN_STOP
|
2013-05-04 04:50:37 +02:00
|
|
|
virsh -c xen:/// setmem $1 $MEM
|
|
|
|
# Add some safety margin
|
|
|
|
virsh -c xen:/// setmaxmem $1 $[ $MEM + 1024 ]
|
2013-06-10 04:28:13 +02:00
|
|
|
# Stop qubesdb daemon now, so VM can restart it later
|
|
|
|
kill `cat /var/run/qubes/qubesdb.$1.pid`
|
2010-06-02 15:50:22 +02:00
|
|
|
sleep 1
|
|
|
|
touch $2
|
2013-05-04 04:50:37 +02:00
|
|
|
if ! virsh -c xen:/// save $1 $2; then
|
2010-09-07 16:00:14 +02:00
|
|
|
rm -f $QMEMMAN_STOP
|
2015-05-15 03:19:28 +02:00
|
|
|
qvm-kill $1
|
2010-09-07 16:00:14 +02:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
rm -f $QMEMMAN_STOP
|
2015-05-15 02:41:18 +02:00
|
|
|
# Do not allow smaller allocation than 400MB. If that small number comes from
|
|
|
|
# an error, it would prevent further savefile regeneration (because VM would
|
|
|
|
# not start with too little memory). Also 'maxmem' depends on 'memory', so
|
|
|
|
# 400MB is sane compromise.
|
|
|
|
if [ "$MEM" -lt 409600 ]; then
|
|
|
|
qvm-prefs -s $1 memory 400
|
|
|
|
else
|
|
|
|
qvm-prefs -s $1 memory $[ $MEM / 1024 ]
|
|
|
|
fi
|
2015-02-11 15:02:33 +01:00
|
|
|
ln -snf $VMDIR /var/lib/qubes/dvmdata/vmdir
|
2010-06-02 15:50:22 +02:00
|
|
|
cd $VMDIR
|
2015-08-04 18:11:32 +02:00
|
|
|
fstype=`df --output=fstype $VMDIR | tail -n 1`
|
|
|
|
if [ "$fstype" = "tmpfs" ]; then
|
|
|
|
# bsdtar doesn't work on tmpfs because FS_IOC_FIEMAP ioctl isn't supported
|
|
|
|
# there
|
|
|
|
tar -cSf saved-cows.tar volatile.img
|
|
|
|
else
|
|
|
|
bsdtar -cSf saved-cows.tar volatile.img
|
|
|
|
fi
|
2013-05-04 04:50:37 +02:00
|
|
|
echo "DVM savefile created successfully."
|