~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
#!/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 [ $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
    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