~ubuntu-branches/debian/stretch/dkms/stretch

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
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#!/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

uname_s=$(uname -s)

_get_kernel_dir() {
    KVER=$1
    case ${uname_s} in
	Linux)		DIR="/lib/modules/$KVER/build" ;;
	GNU/kFreeBSD)	DIR="/usr/src/kfreebsd-headers-$KVER/sys" ;;
    esac
    echo $DIR
}

_check_kernel_dir() {
    DIR=$(_get_kernel_dir $1)
    case ${uname_s} in
	Linux)		test -e $DIR/include ;;
	GNU/kFreeBSD)	test -e $DIR/kern && test -e $DIR/conf/kmod.mk ;;
	*)		return 1 ;;
    esac
    return $?
}

# 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
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
elif [ -d "/usr/src/$NAME-$VERSION" ]; then
    echo "Loading new $NAME-$VERSION DKMS files..."
    dkms add -m $NAME -v $VERSION > /dev/null
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 the current kernel doesn't come from the host of a chroot
if [ `_is_kernel_name_correct $CURRENT_KERNEL` = "yes" ]; then
    # See if it's worth building the module for both the newest kernel
    # and for the current kernel
    if [ -n "$NEWEST_KERNEL" ] && [ ${CURRENT_KERNEL} != ${NEWEST_KERNEL} ]; then
        echo "Building for $CURRENT_KERNEL and $NEWEST_KERNEL"
        KERNELS="$CURRENT_KERNEL $NEWEST_KERNEL"
    else
        echo "Building only for $CURRENT_KERNEL"
    fi
# The current kernel is not useful as it's the host's
else
    echo "It is likely that $CURRENT_KERNEL belongs to a chroot's host"

    # Let's use only the newest kernel
    if [ -n "$NEWEST_KERNEL" ]; then
        KERNELS="$NEWEST_KERNEL"
        echo "Building only for $NEWEST_KERNEL"
    fi
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 _check_kernel_dir $KERNEL; then
            echo "Building initial module for $KERNEL"
            set +e
            dkms build -m $NAME -v $VERSION -k $KERNEL $ARCH > /dev/null
            case $? in
            9)
                set -e
                echo "Skipped."
                continue
                ;;
            0)
                set -e
                echo "Done."
                ;;
            *)
                exit $?
                ;;
            esac
            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