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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
#!/bin/sh
# Copyright (C) 2002-2005 Flavio Stanchina
# Copyright (C) 2005-2006 Aric Cyr
# Copyright (C) 2007 Mario Limonciello
# Copyright (C) 2009 Alberto Milone
set -e
# Check the existence of a kernel named as $1
_is_kernel_name_correct() {
CORRECT="no"
KERNEL_NAME=$1
for kernel in /boot/config-*; do
KERNEL=${kernel#*-}
if [ "${KERNEL}" = "${KERNEL_NAME}" ]; then
CORRECT="yes"
break
fi
done
echo $CORRECT
}
# Get the most recent kernel on Debian based systems. This keeps
# into account both the version and the ABI. If the current kernel
# is the most recent kernel then the function will print a null string.
_get_newest_kernel_debian() {
NEWEST_KERNEL=
NEWEST_VERSION=
NEWEST_ABI=
for kernel in /boot/config-*; do
KERNEL=${kernel#*-}
KERNEL_VERSION=${KERNEL%%-*}
ABI=${KERNEL#*-}
ABI=${ABI%%-*}
if [ -z "$NEWEST_KERNEL" ]; then
# The 1st time get a version which is bigger than $1
COMPARE_TO=$1
else
# Get the biggest version
COMPARE_TO="$NEWEST_VERSION-$NEWEST_ABI"
fi
# if $kernel is greater than $COMPARE_TO
if [ `dpkg --compare-versions "$KERNEL_VERSION-$ABI" gt "$COMPARE_TO" && echo "yes" || \
echo "no"` = "yes" ]; then
NEWEST_KERNEL=$KERNEL
NEWEST_VERSION=$KERNEL_VERSION
NEWEST_ABI=$ABI
fi
done
echo "$NEWEST_KERNEL"
}
# Get the most recent kernel in Rhel based systems. If the current kernel
# is the most recent kernel then the function will print a null string.
_get_newest_kernel_rhel() {
NEWEST_KERNEL=
LAST_INSTALLED_KERNEL=$(rpm -q --whatprovides kernel --last | grep kernel -m1 | cut -f1 -d' ')
LIK_FORMATTED_NAME=$(rpm -q $LAST_INSTALLED_KERNEL --queryformat="%{VERSION}-%{RELEASE}.%{ARCH}\n")
if [ `echo $LIK_FORMATTED_NAME | grep 2.6 >/dev/null` ]; then
# Fedora and Suse
NEWEST_KERNEL=$LIK_FORMATTED_NAME
else
# Hack for Mandriva where $LIK_FORMATTED_NAME is broken
LIK_NAME=$(rpm -q $LAST_INSTALLED_KERNEL --queryformat="%{NAME}\n")
LIK_TYPE=${LIK_NAME#kernel-}
LIK_TYPE=${LIK_TYPE%%-*}
LIK_STRIPPED=${LIK_NAME#kernel-}
LIK_STRIPPED=${LIK_STRIPPED#$LIK_TYPE-}
LIK_STRIPPED_BASE=${LIK_STRIPPED%%-*}
LIK_STRIPPED_END=${LIK_STRIPPED#$LIK_STRIPPED_BASE-}
LIK_FINAL=$LIK_STRIPPED_BASE-$LIK_TYPE-$LIK_STRIPPED_END
NEWEST_KERNEL=$LIK_FINAL
fi
echo $NEWEST_KERNEL
}
# Get the newest kernel on Debian and Rhel based systems.
get_newest_kernel() {
NEWEST_KERNEL=
# Try Debian first as rpm can be installed in Debian based distros
if [ -e /usr/bin/dpkg ]; then
# If DEB based
CURRENT_KERNEL=$1
CURRENT_VERSION=${CURRENT_KERNEL%%-*}
CURRENT_ABI=${CURRENT_KERNEL#*-}
CURRENT_FLAVOUR=${CURRENT_ABI#*-}
CURRENT_ABI=${CURRENT_ABI%%-*}
NEWEST_KERNEL=$(_get_newest_kernel_debian "$CURRENT_VERSION-$CURRENT_ABI")
elif [ `which rpm >/dev/null` ]; then
# If RPM based
NEWEST_KERNEL=$(_get_newest_kernel_rhel)
fi
# Make sure that kernel name that we extracted corresponds to an installed
# kernel
if [ -n "$NEWEST_KERNEL" ] && [ `_is_kernel_name_correct $NEWEST_KERNEL` = "no" ]; then
NEWEST_KERNEL=
fi
echo $NEWEST_KERNEL
}
NAME=$1
VERSION=$2
TARBALL_ROOT=$3
ARCH=$4
UPGRADE=$5
if [ -z "$NAME" ] || [ -z "$VERSION" ]; then
echo "Need NAME, and VERSION defined"
echo "ARCH is optional"
exit 1
fi
KERNELS=$(ls /lib/modules/)
CURRENT_KERNEL=$(uname -r)
#We never want to keep an older version side by side to prevent conflicts
if [ -e "/var/lib/dkms/$NAME/$VERSION" ]; then
echo "Removing old $NAME-$VERSION DKMS files..."
dkms remove -m $NAME -v $VERSION --all
fi
#Load new files, by source package and by tarball
echo "Loading new $NAME-$VERSION DKMS files..."
if [ -d "/usr/src/$NAME-$VERSION" ]; then
dkms add -m $NAME -v $VERSION > /dev/null
fi
if [ -f "$TARBALL_ROOT/$NAME-$VERSION.dkms.tar.gz" ]; then
if ! dkms ldtarball --archive "$TARBALL_ROOT/$NAME-$VERSION.dkms.tar.gz"; then
echo ""
echo ""
echo "Unable to load DKMS tarball $TARBALL_ROOT/$NAME-$VERSION.dkms.tar.gz."
echo "Common causes include: "
echo " - You must be using DKMS 2.1.0.0 or later to support binaries only"
echo " distribution specific archives."
echo " - Corrupt distribution specific archive"
echo ""
echo ""
exit 2
fi
fi
# On 1st installation, let us look for a directory
# in /lib/modules which matches `uname -r`. If none
# is found it is possible that buildd is being used
# and that uname -r is giving us the name of the
# kernel used by the buildd machine.
#
# If this is the case we try to build the kernel
# module for each kernel which has a directory in
# /lib/modules. Furthermore we will have to tell
# DKMS which architecture it should build the module
# for (e.g. if the buildd machine is using a
# 2.6.24-23-xen 64bit kernel).
#
# NOTE: if the headers are not installed then the
# module won't be built, as usual
if [ -z "$UPGRADE" ]; then
echo "First Installation: checking all kernels..."
for KERNEL in $KERNELS; do
if [ ${KERNEL} = ${CURRENT_KERNEL} ]; then
# Kernel found
KERNELS=$CURRENT_KERNEL
break
fi
done
else
KERNELS=$CURRENT_KERNEL
fi
# Here we look for the most recent kernel so that we can
# build the module for it (in addition to doing it for the
# current kernel.
NEWEST_KERNEL=$(get_newest_kernel "$KERNELS")
if [ -n "$NEWEST_KERNEL" ] && [ ${CURRENT_KERNEL} != ${NEWEST_KERNEL} ]; then
echo "Building for $CURRENT_KERNEL and $NEWEST_KERNEL"
KERNELS="$KERNELS $NEWEST_KERNEL"
else
echo "Building only for $CURRENT_KERNEL"
fi
if [ -n "$ARCH" ]; then
if which lsb_release >/dev/null && [ $(lsb_release -s -i) = "Ubuntu" ]; then
case $ARCH in
amd64)
ARCH="x86_64"
;;
lpia|i?86)
ARCH="i686"
;;
esac
fi
echo "Building for architecture $ARCH"
ARCH="-a $ARCH"
fi
for KERNEL in $KERNELS; do
dkms_status=`dkms status -m $NAME -v $VERSION -k $KERNEL $ARCH`
if [ `echo $KERNEL | grep -c "BOOT"` -gt 0 ]; then
echo ""
echo "Module build and install for $KERNEL was skipped as "
echo "it is a BOOT variant"
continue
fi
#if the module isn't yet built, try to build it
if [ `echo $dkms_status | grep -c ": built"` -eq 0 ]; then
if [ ! -L /var/lib/dkms/$NAME/$VERSION/source ]; then
echo "This package appears to be a binaries-only package"
echo " you will not be able to build against kernel $KERNEL"
echo " since the package source was not provided"
continue
fi
if [ -e /lib/modules/$KERNEL/build/include ]; then
echo "Building initial module for $KERNEL"
dkms build -m $NAME -v $VERSION -k $KERNEL $ARCH > /dev/null
echo "Done."
dkms_status=`dkms status -m $NAME -v $VERSION -k $KERNEL $ARCH`
else
echo "Module build for the currently running kernel was skipped since the"
echo "kernel source for this kernel does not seem to be installed."
fi
fi
#if the module is built (either pre-built or just now), install it
if [ `echo $dkms_status | grep -c ": built"` -eq 1 ] &&
[ `echo $dkms_status | grep -c ": installed"` -eq 0 ]; then
dkms install -m $NAME -v $VERSION -k $KERNEL $ARCH
fi
done
|