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
|
#!/bin/bash
vbox_build_id() {
{
echo "$REQUIRED_VBOX_VERSION"
gcc --version 2>&1
echo "${TARGET_KERNEL_LONG}"
echo "2" # incrase this in case something relevant changes in this build script
grep -E '^(# )?CONFIG_' "${KERNEL_HEADERS_DIR}/.config"
} | md5sum | cut -c1-32
}
fetch_source() {
[ -d "${MODULE_WORK_DIR}/src" ] && rm -rf "${MODULE_WORK_DIR}/src"
[ -z "${REQUIRED_VBOX_VERSION}" ] && perror "REQUIRED_VBOX_VERSION is not set!"
local done=
if nfs_cache_avail; then
local id tar
id="$( vbox_build_id )"
pinfo "Build id is $id"
tar="${NFS_CACHE_DIR}/cache/${id}.tar.zstd"
if [ -s "$tar" ]; then
pinfo "Extracting cached vbox build"
if < "$tar" zstd -d -T0 | tar -C "${MODULE_WORK_DIR}" -x; then
touch "$tar" # We use last modified as last used, as atime is unreliable
done=1
fi
pwarning "Extracting cached kernel failed, building..."
fi
fi
if [ -z "$done" ]; then
local BASEVER="${REQUIRED_VBOX_VERSION}"
# In case we have something like 1.2.3a, we need 1.2.3 for the directory name below
[[ "${BASEVER: -1}" =~ ^[0-9]$ ]] || BASEVER="${BASEVER:0:-1}"
local BASE_URL="http://download.virtualbox.org/virtualbox"
local DOWNLOAD_URL="${BASE_URL}/${BASEVER}/VirtualBox-${REQUIRED_VBOX_VERSION}.tar.bz2"
download_untar "$DOWNLOAD_URL" "${MODULE_WORK_DIR}/src" || \
perror "Could not download_untar '$DOWNLOAD_URL' to '${MODULE_WORK_DIR}/src'."
fi
if [ -n "$REQUIRED_EXTPACK" ]; then
# oracle's extension pack
DOWNLOAD_URL="${DOWNLOAD_URL%/*}/Oracle_VM_VirtualBox_Extension_Pack-${BASEVER}.vbox-extpack"
download_untar "$DOWNLOAD_URL" "${MODULE_WORK_DIR}/extpack" || \
perror "Could not download_untar '$DOWNLOAD_URL' to '${MODULE_WORK_DIR}/extpack'."
# Nice, Oracle - files in the tarball are world writable, but vbox refuses to use the extpack that way
chmod -R go-w "${MODULE_WORK_DIR}/extpack"
fi
}
build() (
[ -n "${KERNEL_HEADERS_DIR}" ] || perror "KERNEL_HEADERS_DIR not set, kernel module present?"
local BASEVER="${REQUIRED_VBOX_VERSION}"
# In case we have something like 1.2.3a, we need 1.2.3 for the directory name below
[[ "${BASEVER: -1}" =~ ^[0-9]$ ]] || BASEVER="${BASEVER:0:-1}"
local VBOX_BUILD_DIR="${MODULE_WORK_DIR}/src/VirtualBox-${BASEVER}/build"
# Cached?
local bf="${MODULE_WORK_DIR}/src/.mltk-build-flag"
if [ -e "$bf" ]; then
# Cached, setup vars
source "${VBOX_BUILD_DIR}/env.sh" || perror "Failed to source '${VBOX_BUILD_DIR}/env.sh'."
local VBOX_RELEASE_BUILD_DIR="${VBOX_BUILD_DIR}/linux.${BUILD_PLATFORM_ARCH}/release"
else
cd "${MODULE_WORK_DIR}/src/VirtualBox-${BASEVER}" || \
perror "Could not cd to '${MODULE_WORK_DIR}/src/VirtualBox-${BASEVER}'."
mkdir -p "$VBOX_BUILD_DIR" || perror "Failed to mkdir '$VBOX_BUILD_DIR'."
./configure \
--disable-docs \
--disable-java \
--disable-python \
--disable-libvpx \
--enable-vnc \
--disable-udptunnel \
--with-linux="${KERNEL_HEADERS_DIR}" \
--out-base-dir="${VBOX_BUILD_DIR}" \
|| perror "'configure' failed."
# Newer version SUCK because they ignore --with-linux and require KERN_DIR to be set,
# and forthermode require it to end in "<version>/build", so we need to create a symlink *facepalm*
mkdir -p "kernel/${TARGET_KERNEL_LONG}"
ln -nfs "${KERNEL_HEADERS_DIR}" "kernel/${TARGET_KERNEL_LONG}/build" \
|| perror "Kernel symlink fail ('${KERNEL_HEADERS_DIR}' <- 'kernel/${TARGET_KERNEL_LONG}/build')"
export KERN_DIR="$( readlink -f "kernel" )/${TARGET_KERNEL_LONG}/build"
# Limit job count - can easily OOM
num="$( awk '$1 == "MemTotal:" { print int(0.25 + $2 / (1024*1024)) }' /proc/meminfo )"
(( num > CPU_CORES )) && num="$CPU_CORES"
# the configure script should have created a file called 'env.sh'
source "${VBOX_BUILD_DIR}/env.sh" || perror "Failed to source '${VBOX_BUILD_DIR}/env.sh'."
# copy the LocalConfig.kmk to the build dir to be more LSB-compliant
cp "${MODULE_DIR}/LocalConfig.kmk" "${VBOX_BUILD_DIR}" || \
perror "Failed to cp LocalConfig.kmk to build dir"
cp "${MODULE_DIR}/LocalConfig.kmk" "${VBOX_BUILD_DIR}/../" || \
perror "Failed to cp LocalConfig.kmk to build/../ dir"
kmk -j "$num" all || perror "Failed to execute 'kmk'."
# check the generated build directory, use BUILD_PLATFORM_ARCH defined in env.sh
local VBOX_RELEASE_BUILD_DIR="${VBOX_BUILD_DIR}/linux.${BUILD_PLATFORM_ARCH}/release"
[ -d "${VBOX_RELEASE_BUILD_DIR}" ] || \
perror "No release build dir found under '${VBOX_RELEASE_BUILD_DIR}'. Build failed?"
## Kernel modules
# build kernel modules from the release dir
cde "${VBOX_RELEASE_BUILD_DIR}/bin/src"
make \
KERN_DIR="${KERNEL_HEADERS_DIR}" \
KERN_VER="${TARGET_KERNEL_LONG}" \
|| perror "Build kernel modules failed."
# Cache
touch "$bf"
if nfs_cache_avail; then
local id tar
id="$( vbox_build_id )"
tar="${NFS_CACHE_DIR}/cache/${id}.tar.zstd"
pinfo "Copying built vbox to NFS cache with id $id"
mkdir -p "$( dirname "$tar" )"
tar -C "${MODULE_WORK_DIR}" -c -k src | zstd -T0 -2 -z > "$tar" \
|| pwarning "Could not write vbox to NFS cache"
fi
fi
# the resulting linux.<arch>/release/bin folder contains the whole build,
# copy it over to usr/lib/virtualbox
mkdir -p "${MODULE_BUILD_DIR}/usr/lib/virtualbox" || \
perror "Failed to mkdir '${MODULE_BUILD_DIR}/usr/lib/virtualbox'."
cp -r "${VBOX_RELEASE_BUILD_DIR}/bin/"* "${MODULE_BUILD_DIR}/usr/lib/virtualbox" || \
perror "Failed to cp -r '${VBOX_RELEASE_BUILD_DIR}/bin' to '${MODULE_BUILD_DIR}/usr/lib/virtualbox'."
# set suid bits
for BIN in VBoxHeadless VBoxNetAdpCtl VBoxNetDHCP VBoxNetNAT VBoxSDL VirtualBoxVM; do
if ! [ -e "${MODULE_BUILD_DIR}/usr/lib/virtualbox/$BIN" ]; then
pwarning "No such file: '${MODULE_BUILD_DIR}/usr/lib/virtualbox/$BIN', cannot add suid bit."
continue
fi
chmod u+s "${MODULE_BUILD_DIR}/usr/lib/virtualbox/${BIN}" || perror "Failed to set suid bit on '${BIN}'."
done
# Copy kernel modules
cde "${VBOX_RELEASE_BUILD_DIR}/bin/src"
mkdir -p "${MODULE_BUILD_DIR}/lib/modules/vbox" || \
perror "Failed to mkdir '${MODULE_BUILD_DIR}/lib/modules/vbox'."
for MOD in $(find ./* -maxdepth 0 -type d); do
[ -e "$MOD.ko" ] || perror "Module '$MOD' was not built!"
cp "$MOD.ko" "${MODULE_BUILD_DIR}/lib/modules/vbox/" || \
perror "Failed to cp $MOD.ko to '${MODULE_BUILD_DIR}/lib/modules/vbox/'."
done
if [ -n "$REQUIRED_EXTPACK" ]; then
# finally copy the extension pack files, everthing is needed as the subfolders
# target the guest architectures and not that of the host!
local VBOX_EXTPACK_DIR="${MODULE_BUILD_DIR}/usr/lib/virtualbox/ExtensionPacks/Oracle_VM_VirtualBox_Extension_Pack"
cp -ar "${MODULE_WORK_DIR}/extpack" "${VBOX_EXTPACK_DIR}" || \
perror "Failed to cp '${MODULE_WORK_DIR}/extpack' to '${VBOX_EXTPACK_DIR}'."
chown -R root:root "${VBOX_EXTPACK_DIR}" || \
perror "Failed to chown '${VBOX_EXTPACK_DIR}' to root:root."
fi
# od binary
local OD_BIN="$(which od 2>/dev/null)"
if [ -n "$OD_BIN" ] && [ -f "$OD_BIN" ]; then
tarcopy "$OD_BIN" "$MODULE_BUILD_DIR"
fi
true
)
post_copy() {
groupadd --system vboxusers
add_to_group demo vboxusers
}
|