blob: b10623be95df8bce4eb662588113bc0437bebf96 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
###########################################################
# Include: Setup dnbd for image access, nfs/cifs fallback #
###########################################################
# This will currently make sure that the variable
# VM_DISKFILE_RO is set which will contain the
# absolute path to the disk image to use for the vm
# session.
# When using DNBD3 this will differ from SRC_IMG_ABSOLUTE,
# otherwise it will be identical.
# In the future DNBD3 (or something else) might provide
# a CoW layer so we don't need snapshots etc. anymore.
# This include should set VM_DISKFILE_RW in that case to
# indicate to the virt plugin that it doesn't need to
# handle creating a temporary CoW layer itself.
# Helper to cleanup the image mounted with dnbd3-fuse
cleanup_dnbd3() {
if ! isset DNBD3_MOUNT_POINT; then
writelog "'DNBD3_MOUNT_POINT' is not set! Aborting DNBD3 cleanup."
return 1
fi
# try to umount it now
for timeout in 1 1 1 FAIL; do
fusermount -u "${DNBD3_MOUNT_POINT}" && break
writelog "dnbd3 still busy...."
[ "$timeout" = "FAIL" ] && break
sleep "$timeout"
done
}
setup_dnbd3 () {
# Mount path for images mounted with dnbd3-fuse
declare -rg DNBD3_MOUNT_POINT="${TMPDIR}/dnbd3fuse.mnt"
mkdir -p "${DNBD3_MOUNT_POINT}"
# start dnbd3-fuse in subshell
local DNBD3_TMPLOG="${TMPDIR}/dnbd3fuse.log"
local DNBD3_EXITFLAG="${TMPDIR}/dnbd3exit$RANDOM"
local TIMEOUT VM_DISKFILE_REVISION
rm -f -- "${DNBD3_EXITFLAG}"
(
dnbd3-fuse -f -o allow_other,max_readahead=262144 -h "${SLX_DNBD3_SERVERS}" -i "${SRC_IMG_RELATIVE}" "${DNBD3_MOUNT_POINT}" > "${DNBD3_TMPLOG}" 2>&1
RET=$?
touch "${DNBD3_EXITFLAG}"
if [ "$RET" != "0" ]; then
writelog "dnbd3-fuse stopped working (Exit code $RET)"
slxlog "virt-dnbd3-fuse" "dnbd3-fuse stopped/refused serving '${SRC_IMG_RELATIVE}' from '${SLX_DNBD3_SERVERS}' with error code: $RET" "${DNBD3_TMPLOG}"
fi
) &
# give it a bit of time
usleep 250000
# check if we have the image
for TIMEOUT in 0.5 1 1 1 1 OUT; do
if [ -r "${DNBD3_MOUNT_POINT}/img" ]; then
VM_DISKFILE_REVISION="$(grep -m 1 "^Revision:" "${DNBD3_MOUNT_POINT}/status" | cut -d" " -f2)"
VM_DISKFILE_RO="${DNBD3_MOUNT_POINT}/img"
writelog "DNBD3: ${SRC_IMG_RELATIVE} on ${VM_DISKFILE_RO} with rid ${VM_DISKFILE_REVISION}"
add_cleanup "cleanup_dnbd3"
break
fi
[ "$TIMEOUT" = "OUT" -o -e "$DNBD3_EXITFLAG" ] && break
sleep "$TIMEOUT"
done
if isempty VM_DISKFILE_RO; then
slxlog "virt-dnbd3" "No dnbd3 server for ${SRC_IMG_RELATIVE} found, trying NFS/CIFS..." "$DNBD3_TMPLOG"
writelog "No working dnbd3 server found :-("
fi
}
setup_fallback() {
# Maybe we're reading a dnbd3 directory with RIDs encoded into the filename - use latest one
unset VM_DISKFILE_REVISION
local VM_DISKFILE_REVISION=$(ls -1 "${SRC_IMG_ABSOLUTE}.r"* | grep -E -o '\.r[0-9]+$' | grep -o -E '[0-9]+$' | sort -n | tail -n 1)
if notempty VM_DISKFILE_REVISION; then
# found
VM_DISKFILE_RO="${SRC_IMG_ABSOLUTE}.r${VM_DISKFILE_REVISION}"
elif [ -e "${SRC_IMG_ABSOLUTE}" ]; then
# try name we got from xml in the first place
VM_DISKFILE_RO="${SRC_IMG_ABSOLUTE}"
fi
}
## MAIN PART / Sanity checks ##
setup_image_access() {
writelog "Setting up virtual hard disk access for virtualizer/emulator ..."
unset VM_DISKFILE_RO VM_DISKFILE_RW
declare -g VM_DISKFILE_RO VM_DISKFILE_RW
run_hooks "image-access"
if [ -n "$VM_DISKFILE_RW" ]; then
writelog "A hook in setup_image_access supplied a writable diskfile. Not running default setup."
elif [ -n "$VM_DISKFILE_RO" ]; then
writelog "A hook in setup_image_access supplied a read-only diskfile. Not running default setup."
else
setup_image_access_default
fi
readonly VM_DISKFILE_RO VM_DISKFILE_RW
if [ -n "$VM_DISKFILE_RW" ]; then
writelog "\tVM disk file (RW):\t\t$VM_DISKFILE_RW"
if ! [ -s "$VM_DISKFILE_RW" ]; then
writelog ".... not found!"
EXIT_TYPE="user" EXIT_REASON="Schreibbare VM nicht gefunden. Adminmodus fehlgeschlagen." cleanexit 1
fi
if ! [ -w "$VM_DISKFILE_RW" ]; then
writelog ".... not writable!"
EXIT_TYPE="user" EXIT_REASON="VM-Image auf schreibbarem VM-Speicher nicht schreibbar. Adminmodus fehlgeschlagen." cleanexit 1
fi
elif [ -n "$VM_DISKFILE_RO" ]; then
writelog "\tVM disk file (RO):\t\t$VM_DISKFILE_RO"
if ! [ -s "$VM_DISKFILE_RO" ]; then
writelog ".... not found!"
EXIT_TYPE="user" EXIT_REASON="VM-Image nicht gefunden." cleanexit 1
fi
if ! [ -r "$VM_DISKFILE_RO" ]; then
writelog ".... not readable!"
EXIT_TYPE="user" EXIT_REASON="VM-Image nicht lesbar." cleanexit 1
fi
else
EXIT_TYPE="user" EXIT_REASON="Kein VM-Image Dateiname angegeben/gefunden." cleanexit 1
fi
}
setup_image_access_default() {
# See if we should setup dnbd3 image access at all
if ! check_dep dnbd3-fuse fusermount; then
writelog "\tCan't use dnbd3 as dnbd3-fuse/fusermount binaries are not in PATH"
elif ! isset SRC_IMG_RELATIVE; then
writelog "\tCan't use dnbd3 as SRC_IMG_RELATIVE is not set"
elif isempty SLX_DNBD3_SERVERS || [ "x${SLX_VM_DNBD3}" != "xyes" ]; then
writelog "\tCan't use dnbd3 as no servers are given in config, or SLX_VM_DNBD3 is not set to yes"
else
# register setup_dnbd3 as start hook after sourcing this include
writelog "Trying image access via DNBD3..."
setup_dnbd3
fi
# VM_DISKFILE_RO will be empty if dnbd3 is not used or failed to connect.
if isempty VM_DISKFILE_RO; then
# try to fallback to access the image via NFS/CIFS filesystem
writelog "Trying fallback image access via NFS/CIFS..."
setup_fallback
fi
}
call_post_source setup_image_access
|