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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
#!/bin/ash
# This scripts runs as root and prepares the configuration
# for the dnbd3 server (...)
ERRLOG="/run/dnbd3-proxy.err"
[ -s "$ERRLOG" ] && exit 0 # already ran and failed, don't do it again
errormsg () {
echo "$@" >> "$ERRLOG"
slxlog -s -e "dnbd3-setup" "$@"
}
# Get size of disk/device at given path, in MB
disksize () {
df -k "$1" | tail -n 1 | awk '{ print substr($2, 0, length($2)-3) }'
}
# Creates the DNBD3 server configuration under DNBD3_CONF_DIR
DNBD3_CONF_DIR="/etc/dnbd3-server"
if ! mkdir -p "${DNBD3_CONF_DIR}"; then
errormsg "Failed to create '${DNBD3_CONF_DIR}'."
fi
# Checks if the persistent partition (MBR-ID 45 / GPT-LABEL OpenSLX-ID45)
# is present, fallback to /tmp
DNBD3_BASE_DIR="/opt/openslx/persistent"
if grep -q "^/dev/.* ${DNBD3_BASE_DIR} .*rw" /proc/mounts \
&& [ -k "${DNBD3_BASE_DIR}/data" ] \
&& [ "$(disksize "${DNBD3_BASE_DIR}/data")" -gt 12000 ]; then
# setup_partitions creates a data folder in ID45
# TODO: Partition might be filled with garbage belonging to other users, so
# the usable space for dnbd3 might be much lower.
# avail = "disk size" - "du -s $DNBD3_BASE_DIR"
DNBD3_BASE_DIR="${DNBD3_BASE_DIR}/data"
else
# try /tmp fallback
DNBD3_BASE_DIR="/tmp"
if ! grep -q '^/dev/.* '"${DNBD3_BASE_DIR}"' .*rw' /proc/mounts \
|| ! [ "$(disksize "${DNBD3_BASE_DIR}")" -gt 12000 ]; then
# no sane fallback possible
errormsg "Neither a persistent part (ID45) nor /tmp (ID44) are available, or they are < 12GB"
fi
fi
# now try to create the actual folder used by the server
DNBD3_DATA_DIR="${DNBD3_BASE_DIR}/dnbd3"
if ! mkdir -p "${DNBD3_DATA_DIR}"; then
for i in 0 1 2 3 4 5 $RANDOM $RANDOM; do
if mkdir -p "${DNBD3_BASE_DIR}/dnbd3.$i"; then
DNBD3_DATA_DIR="${DNBD3_BASE_DIR}/dnbd3.$i"
break
fi
done
fi
if [ ! -d "${DNBD3_DATA_DIR}" ]; then
errormsg "Failed to create '${DNBD3_BASE_DIR}(.[0-$i])'"
fi
if ! chown -R dnbd3:dnbd3 "${DNBD3_DATA_DIR}"; then
errormsg "Failed to chown '${DNBD3_DATA_DIR}' to dnbd3."
fi
if ! chmod -R go-w,u+rwX "${DNBD3_DATA_DIR}"; then
errormsg "Failed to chmod '${DNBD3_DATA_DIR}' to dnbd3."
fi
# Done with sanity checks, now create configs: server.conf & alt-servers
# Using the information given by the server in /opt/openslx/config
. /opt/openslx/config
DNBD3_SPARSE="false"
DNBD3_BGR="false"
DNBD3_LOOKUP="false"
DNBD3_SERVER_PENALTY=2000 # no BGR = don't like other servers connecting so much
if [ -n "${SLX_DNBD3_BGR}" ]; then
DNBD3_BGR="true"
DNBD3_SERVER_PENALTY=500 # much better
# Only do chained lookup of image if we're a global proxy with BGR
[ -z "${SLX_DNBD3_WHITELIST}" ] && DNBD3_LOOKUP="true"
fi
if [ -n "${SLX_DNBD3_SPARSE}" ]; then
DNBD3_SPARSE="true"
fi
# Determine if we need sparse mode, or override BGR
cache_size=$(disksize "$DNBD3_DATA_DIR")
if ! [ "$cache_size" -gt 120000 ]; then
# less than 120GiB or NaN, force
[ "$DNBD3_BGR" = "true" ] && slxlog -s -e "dnbd3-setup-small" "Cache partition < 120GiB, forcing background replication OFF and sparse mode ON"
DNBD3_SPARSE="true"
DNBD3_BGR="false"
DNBD3_SERVER_PENALTY=5000
DNBD3_LOOKUP="false"
elif [ "$cache_size" -gt 2000000 ]; then
# force non-sparse on > 2TiB
DNBD3_SPARSE="false"
fi
DNBD3_PORT=5003
rm -f "${DNBD3_CONF_DIR}/server.conf"
# Refer to http://git.openslx.org/dnbd3.git/tree/conf for configuration options
cat << EOF > "${DNBD3_CONF_DIR}/server.conf"
[dnbd3]
listenPort=${DNBD3_PORT}
basePath=${DNBD3_DATA_DIR}
serverPenalty=${DNBD3_SERVER_PENALTY}
clientPenalty=0
isProxy=true
backgroundReplication=${DNBD3_BGR}
lookupMissingForProxy=${DNBD3_LOOKUP}
sparseFiles=${DNBD3_SPARSE}
removeMissingImages=false
uplinkTimeout=5000
clientTimeout=15000
[logging]
consoleMask=ERROR WARNING MINOR INFO
EOF
MY_IPS=$(ip a | grep '^\s*inet\s' | awk '{print $2}')
# helper to echo given list of IPs to ${DNBD3_CONF_DIR}/alt-servers
# optionally takes a single char prefix as first param and
# adds it to the IP (for private dnbd3 servers)
# Also sets FOUND_SAT if satellite IP was seen
add_alt_server() {
local PRE=
[ "x$1" = "x-" ] && PRE='-' && shift
for ALT in "$@"; do
for ip in $MY_IPS; do
[ "x$ALT" = "x${ip%/*}" ] && return 0 # Ignore self
done
echo "${PRE}${ALT}" >> "${DNBD3_CONF_DIR}/alt-servers"
[ "x${ALT}" = "x${SLX_PXE_SERVER_IP}" ] && FOUND_SAT="oui"
done
return 0
}
rm -f "${DNBD3_CONF_DIR}/alt-servers"
FOUND_SAT=
add_alt_server ${SLX_DNBD3_PUBLIC}
add_alt_server '-' ${SLX_DNBD3_PRIVATE}
# To this day, only the sat IP is in SLX_KCL_SERVERS afaik
[ -z "${FOUND_SAT}" ] && add_alt_server ${SLX_KCL_SERVERS}
chmod -R a+Xr "${DNBD3_CONF_DIR}"
# create rpc.acl to allow the satellite only
rm -f "${DNBD3_CONF_DIR}/rpc.acl"
for SRV in ${SLX_KCL_SERVERS}; do
echo "$SRV ALL" >> "${DNBD3_CONF_DIR}/rpc.acl"
done
rm -f "/opt/openslx/iptables/rules.d/99-dnbd3"
# now create iptables helper rules
if [ -n "${SLX_DNBD3_WHITELIST}" ]; then
DNBD3_IPTABLES_CONF="$(mktemp)"
echo '#!/bin/ash' > "${DNBD3_IPTABLES_CONF}"
for CIDR in ${SLX_DNBD3_WHITELIST}; do
echo "iptables -I ipt-helper-INPUT 1 -i br0 -p tcp -s ${CIDR} --dport ${DNBD3_PORT} -j ACCEPT"
done >> "${DNBD3_IPTABLES_CONF}"
echo "iptables -A ipt-helper-INPUT -i br0 -p tcp --dport ${DNBD3_PORT} -j REJECT" >> "${DNBD3_IPTABLES_CONF}"
chmod +x "${DNBD3_IPTABLES_CONF}"
mv -f "$DNBD3_IPTABLES_CONF" "/opt/openslx/iptables/rules.d/99-dnbd3"
fi
(
echo "*******************"
echo "*** DNBD3 Proxy ***"
echo "*******************"
) | tee -a "/etc/issue" >> "/opt/openslx/etc/issue.template"
# Create a crontab for rebooting - if everything is fine, once a weekend,
# on failure, reboot every night, hoping things will get better (...)
M=$(( RANDOM % 60 ))
H=$(( RANDOM % 5 ))
if [ -s "$ERRLOG" ]; then
W="*"
else
W="0"
fi
cat > "/etc/cron.d/dnbd3-reboot" <<EOF
# OpenSLX: Reboot proxy at night
SHELL=/bin/ash
PATH=/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin
$M $H * * $W root reboot
EOF
exit 0
|