Files
gitea-pages/admin-guide/legacy/misc/kernelmodulee1000eupdateforsl5.1.rst
2021-05-05 14:24:27 +02:00

27 KiB

Kernel Module E1000E Update For SL5.1

This document is almost certainly obsolete, hence I just include the unformatted POD source of the original:

=head2 References

=over 4

=item *

http://support.intel.com/support/

=back

=head2 Introduction

The Intel Gigabit ethernet card F<82567LM>, which comes with the
new Fujitsu Siemens computers F<Celsius W370>, F<Esprimo p7935 e80>,
F<Esprimo e7935 e80> and F<Lifebook e8420>, contemporary does not work
out of the box in SL51 (and for sure others) because the updated version
of the e1000e driver is not available yet in Scientific Linux.

As a consequence of this the network installation is not working for this
kind of hardware, because
the SL5.1 installation kernel, too, is not coming with the proper driver.

This documents describes a quick workaround, Solution 1, and a more profound
procedure, Solution 2, to solve this issue. A third alternative, Solution 3,
is shortly mentioned, but could not be finalized.

=head3 Solution 1

For the network installation
via PXE boot a second SL5 compatible network card has to be plugged in. When the
installation has finished, an updated version of the
e1000e driver, that supports the mentioned hardware can be downloaded
from the Intel website (see References) and installed on the system.

=head3 Solution 2

Use the SL5.3 kernel, the e1000e driver of which does support the F<82567LM> hardware,
to install the SL5.1.

First, the PXE boot environment has to be setup with the SL5.3 kernel and the related
initial ramdisk.

Second, the F<.buildstamp> in the initial ramdisk of SL5.3 has to be replaced by the
F<.buildstamp> of SL5.1. This facilitates the SL5.3 installer to use the SL5.1 installation
tree. Therefore the ramdisk has to be unpacked, modified and
repacked (it is a gzipped cpio archive).

Third, build a kernel module e1000e RPM for SL5.1 which will be installed during the SL5.1
installation by means of a custom key F<e1000e>.

Fourth, setup the F<e1000e> custom key.

=head3 Solution 3

Note: This was tried but does not work yet.

For the network installation compile the new e1000e driver for the installation kernel and put it into
the corresponding initial ramdisk.

For the running system build the e1000e RPMS for the current kernel/architecture combinations
and install the RPMS during the kickstart process.

When the kernel is updated the corresponding e1000e RPMS have to be rebuilt and put into
the update repository.

=head2 Procedure for Solution 1

Get the tarball, extract it and build the driver following
the instructions in the README of the tarball.

Get the tarball and extract it.

    # [root@pc7637]
    # uname -a
    Linux pc7637 2.6.18-92.1.22.el5PAE #1 SMP Tue Dec 16 07:10:07 EST 2008 i686 i686 i386 GNU/Linux
    # cd /tmp/
    # wget http://downloadmirror.intel.com/17069/eng/e1000e-0.4.1.7.tar.gz
    # tar xfz e1000e-0.4.1.7.tar.gz

Install the corresponding kernel source RPM.

    # rpm -ivh /afs/psi.ch/software/mirror/scientific/5x/SRPMS/vendor/kernel-2.6.18-92.1.22.el5.src.rpm

Build the RPM for the running kernel.

    # rpmbuild -tb e1000e-0.4.1.7.tar.gz
    ...
    Wrote: /usr/src/redhat/RPMS/i386/e1000e-0.4.1.7-1.i386.rpm
    ...

Install the driver RPM.

    # rpm -ivh /usr/src/redhat/RPMS/i386/e1000e-0.4.1.7-1.i386.rpm

Becaus this is a newly installed host, disable older kernels in grub,
because the kernel module e1000e is only valid for the running kernel.
However the older kernels should be removed later, if there are no needs to run
them.

    # vi /boot/grub/grub.conf

The resulting RPM e1000e-0.4.1.7-1.i386.rpm was built on a FS Celsius W370
after Network installation via an old plugged in 3COM network card
as 2nd network device. After installation of this RPM the 3COM
card was removed and the on board Intel Gigabit network card
was running with the new e1000e kernel module.

=over 4

=item Note:

This RPM contains only the module for an SL51 PAE kernel.

    /lib/modules/2.6.18-92.1.22.el5PAE/kernel/drivers/net/e1000e/e1000e.ko.new

=back

=for comment
##################################################################################3

=head2 Procedure for Solution 2

=head3 Setup the PXE Boot Environment for the New Kickstart Installation

Add the following labels to 
F</afs/psi.ch/service/linux/tftpboot/pxelinux.cfg/default.testing>.
At the time of writing they are used for testing, their names will probably
be changed later on.

Note: You can take the same kickstart configuration files as for the default
SL51 installation, under the labels sl5 and sl564.

    label sl53t32
      kernel scientific/53for51install/i386/vmlinuz
      append initrd=scientific/53for51install/i386/initrd.img ksdevice=eth0 \
        ks=nfs:129.129.190.59:/master/linux/kickstart/configs/sl51-a-ks.cfg noipv6

    label sl53t64
      kernel scientific/53for51install/x86_64/vmlinuz
      append initrd=scientific/53for51install/x86_64/initrd.img ksdevice=eth0 \
        ks=nfs:129.129.190.59:/master/linux/kickstart/configs/sl51-64-a-ks.cfg noipv6

Copy the installation kernel and the initial ramdisk to the tftpboot
location given in the respective labels above.

    # cd /afs/psi.ch/service/linux/tftpboot/scientific/
    # mkdir -p 53for51install/i386 53for51install/x86_64

    # cd 53for51install/i386/
    # wget http://ftp.scientificlinux.org/linux/scientific/5rolling/i386/images/pxeboot/vmlinuz
    # wget http://ftp.scientificlinux.org/linux/scientific/5rolling/i386/images/pxeboot/initrd.img

    # cd ../x86_64/
    # wget http://ftp.scientificlinux.org/linux/scientific/5rolling/x86_64/images/pxeboot/vmlinuz
    # wget http://ftp.scientificlinux.org/linux/scientific/5rolling/x86_64/images/pxeboot/initrd.img

Before proceeding with the next section test whether the basic setup is working.
Therefore boot F<sl53t32> and F<sl53t64> on a test machine.

This should setup the network connections, start the kickstart
till to the point when it runs the pre installation scripts.

=head3 Modify the Initial Ramdisk, Example for x86_64

Unpack the initial ramdisk image of SL5.3.

    # cd /afs/psi.ch/service/linux/tftpboot/scientific/53for51install/x86_64/
    # mkdir tmp
    # cd tmp
    # zcat ../initrd.img | cpio -ivd

The content of the F<.buildstamp> will be something alike.

    # cat .buildstamp
    200902111740.x86_64
    Scientific Linux
    53
    SL
    your distribution provided bug reporting tool.

Now replace this F<.buildstamp> file with the one
of the SL5.1 installation tree. Therefore you also have to
unpack the ramdisk.

    # cd /afs/psi.ch/software/linux/dist/scientific/51/x86_64/images/pxeboot/
    # mkdir tmp
    # cd tmp
    # zcat ../initrd.img | cpio -ivd

Here we have the following F<.buildstamp>.

    # cat .buildstamp
    200801141434.x86_64
    Scientific Linux
    51
    SL
    your distribution provided bug reporting tool.

    # cp -i .buildstamp \
    #   /afs/psi.ch/service/linux/tftpboot/scientific/53for51install/x86_64/tmp/

Clean up.

    # cd ..
    # rm -rf tmp

Repack the initial ramdisk of SL5.3 x86_64.
For this part the commands were taken from F</sbin/mkinitrd> of
the SL5.1 RPM F<mkinitrd-5.1.19.6-19> and put into a script,
because repacking the ramdisk without the same command options
as from the F</sbin/mkinitrd> script fails.

=opentwisty

    #  # Function from /sbin/mkinitrd
    #  findall() {
    #      echo nash-find "$@" | /sbin/nash --force --quiet
    #  }
        #   
    #  # Architecture
    #  ARCH="x86_64"
        #   
    #  # Set file locations:
    #  #   The temporary directory in the tftpboot directory
    #  #   where the initial ramdisk is extracted to.
    #  MNTIMAGE="/afs/psi.ch/service/linux/tftpboot/scientific/53for51install/$ARCH/tmp"
        #   
    #  #   The name of the new ramdisk, not to overwrite the original one
    #  target="initrd.img_new"
        #   
    #  # Start processing
    #  if test ! -d $MNTIMAGE 
    #  then 
    #          echo "Error: $MNTIMAGE does not exist."
    #          exit
    #  fi
        #   
    #  if test -e ${MNTIMAGE}/../initrd.img_new.cpio
    #  then
    #          echo -n "${MNTIMAGE}/../initrd.img_new.cpio exists. Shall I remove it (y/N)?"
    #          read a
    #          if test "$a" = "y"
    #          then
    #           rm -f ${MNTIMAGE}/../initrd.img_new.cpio
    #          fi
    #  fi
        #   
    #  # Create the empty ramdisk file (from /sbin/mkinitrd)
    #  IMAGE=`mktemp ${MNTIMAGE}/../initrd.img_new.cpio`
        #   
    #  # Fill it as cpio archive (from /sbin/mkinitrd)
    #  (cd $MNTIMAGE; findall . | cpio --quiet -c -o) >| $IMAGE || exit 1
        #   
    #  # Compress the cpio archive (from /sbin/mkinitrd)
    #  gzip -9 < $IMAGE >| ${MNTIMAGE}/../$target
        #   
    #  echo "Check the new initial ramdisk at"
    #  echo "/afs/psi.ch/service/linux/tftpboot/scientific/53for51install/$ARCH/"
    #  echo

=closetwisty

Go to the tftpboot direcory and setup the new initial ramdisk.
Make also a backup of the original one.

    # cd /afs/psi.ch/service/linux/tftpboot/scientific/53for51install/x86_64/
    # mv initrd.img initrd.img_orig
    # ln -s initrd.img_new initrd.img

Now test the PXE boot kickstart installation using the
label F<sl53t64>.

If everything looks fine clean up and go to the next section
or repeat this part for the i386 architecture.

    # rm -rf tmp/ initrd.img_new.cpio

=head3 Build the e1000e Kernel Module RPM, Example for x86_64

Go to the build system tux50-64 and download the e1000e sources
and get the spec file.

    # [gasser_m@tux50-64]
    # cd /scratch/gasser_m/rpm_topdir/SOURCES/
    # wget http://downloadmirror.intel.com/17069/eng/e1000e-0.4.1.7.tar.gz
    # tar xfz e1000e-0.4.1.7.tar.gz
    # cp e1000e-0.4.1.7/e1000e.spec ../SPECS/
    # rm -rf e1000e-0.4.1.7
    # cd ../SPECS/
    # cp e1000e e1000e_orig

Note, you can build the RPM directly from this tarball, but here we want to
change the name of the built RPM to apply our PSI naming convention for kernel
modules, thus we need to edit the spec file before building.

    # vi e1000e.spec

=opentwisty

    #### begin e1000e.spec

    %define driver_name e1000e
    %define kernel 2.6.18-92.1.22.el5

    %define pkg_name kernel-module-%{driver_name}-%{kernel}

    Name: %{pkg_name}
    Summary: Intel(R) Gigabit Ethernet Connection
    Version: 0.4.1.7
    Release: 1
    Source: %{driver_name}-%{version}.tar.gz
    Vendor: Intel Corporation
    Packager: Marc Gasser <marc.gasser@psi.ch>
    License: GPL
    ExclusiveOS: linux
    Group: System Environment/Kernel
    Provides: %{driver_name}
    URL: http://support.intel.com/support/go/linux/e1000e.htm
    BuildRoot: %{_tmppath}/%{driver_name}-%{version}-root
    # do not generate debugging packages by default - newer versions of rpmbuild
    # may instead need:
    #%define debug_package %{nil}
    %debug_package %{nil}
    # macros for finding system files to update at install time (pci.ids, pcitable)
    %define find() %(for f in %*; do if [ -e $f ]; then echo $f; break; fi; done)
    %define _pciids   /usr/share/pci.ids        /usr/share/hwdata/pci.ids
    %define _pcitable /usr/share/kudzu/pcitable /usr/share/hwdata/pcitable /dev/null
    %define pciids    %find %{_pciids}
    %define pcitable  %find %{_pcitable}
    Requires: kernel, fileutils, findutils, gawk, bash

    %description
    This package contains the Linux driver for the Intel(R) Gigabit Family of Server Adapters.

    ########################### begin RPM build section

    %prep
    %setup -n %{driver_name}-%{version}

    %build
    mkdir -p %{buildroot}

    KV=%{kernel}
    KA=%{_arch}
    KV_BASE=$(echo $KV | sed '{ s/hugemem//g; s/smp//g; s/enterprise//g; }' )

    if [ -e /usr/src/kernels ] && [ $(echo $KV_BASE | grep "^2.6") ]; then
        if [ -e /etc/redhat-release ]; then
            KSP=$(ls /lib/modules | grep $KV_BASE)
            for K in $KSP ; do
                if [ $KA == "x86_64" ] && \
                   [ $(echo $K | grep hugemem) ]; then
                    # Include path for x86_64 hugemem is broken
                    # on RHEL4
                    continue
                fi
                make -C src clean
                make -C src KSP=/lib/modules/$K/build \
                    INSTALL_MOD_PATH=%{buildroot} \
                    KVERSION=$k \
                    MANDIR=%{_mandir} \
                    CFLAGS_EXTRA="$CFLAGS_EXTRA" install
            done
        else
            make -C src clean
            make -C src INSTALL_MOD_PATH=%{buildroot} \
                MANDIR=%{_mandir} install
        fi
    else
        SwitchRHKernel () {
            CFLAGS_EXTRA=""
            for K in $2 ; do
                if [ $K == $1 ] ; then
                    CFLAGS_EXTRA="$CFLAGS_EXTRA -D__BOOT_KERNEL_$K=1"
                else
                    CFLAGS_EXTRA="$CFLAGS_EXTRA -D__BOOT_KERNEL_$K=0"
                fi
            done
        }

        KSP="/lib/modules/$KV/build
             /usr/src/linux-$KV
             /usr/src/linux-$(echo $KV | sed 's/-.*//')
             /usr/src/kernel-headers-$KV
             /usr/src/kernel-source-$KV
             /usr/src/linux-$(echo $KV | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/')
             /usr/src/linux"

        KSRC=$(for d in $KSP ; do [ -e $d/include/linux ] && echo $d; echo;  done)
        KSRC=$(echo $KSRC | awk '{ print $1 }')

        if [ -e $KSRC/include/linux/rhconfig.h ] ; then
            RHKL=$(grep 'BOOT_KERNEL_.* [01]' /boot/kernel.h |
                   sed 's/.*BOOT_KERNEL_\(.*\) [01]/\1/')
            if echo $RHKL | grep BIGMEM
            then
                RHKL=$(echo $RHKL | sed 's/ENTERPRISE//')
            fi
            if echo $RHKL | grep HUGEMEM
            then
                RHKL=$(echo $RHKL | sed 's/BIGMEM//')
            fi
            for K in $RHKL ; do
                SwitchRHKernel $K "$RHKL"
                make -C src clean
                if [ $KA == "x86_64" ] ; then
                    CFLAGS_EXTRA="$CFLAGS_EXTRA -D__MODULE_KERNEL_x86_64=0 -D__MODULE_KERNEL_ia32e=1"
                fi
                make -C src INSTALL_MOD_PATH=%{buildroot} \
                    MANDIR=%{_mandir} CFLAGS_EXTRA="$CFLAGS_EXTRA" install
            done
        else
            make -C src clean
            make -C src INSTALL_MOD_PATH=%{buildroot} MANDIR=%{_mandir} install
        fi
    fi

    %install
    # Append .new to driver name to avoid conflict with kernel RPM
    echo "# Going to " %{buildroot}
    cd %{buildroot}
    find lib -name "e1000e.*o" -exec mv {} {}.new \; \
         -fprintf %{_builddir}/%{driver_name}-%{version}/file.list "/%p.new\n"


    %clean
    rm -rf %{buildroot}

    %files -f %{_builddir}/%{driver_name}-%{version}/file.list
    %defattr(-,root,root)
    %{_mandir}/man7/e1000e.7.gz
    %doc COPYING
    %doc README
    %doc file.list
    %doc pci.updates

    ########################### end RPM build section

    ########################### begin RPM installation section

    %post
    FL="%{_docdir}/%{name}-%{version}/file.list
        %{_docdir}/%{name}/file.list"
    FL=$(for d in $FL ; do if [ -e $d ]; then echo $d; break; fi;  done)

    if [ -d /usr/local/lib/%{name} ]; then
        rm -rf /usr/local/lib/%{name}
    fi
    if [ -d /usr/local/share/%{name} ]; then
        rm -rf /usr/local/share/%{name}
    fi

    echo "original pci.ids saved in /usr/local/share/%{name}";
    if [ "%{pcitable}" != "/dev/null" ]; then
        echo "original pcitable saved in /usr/local/share/%{name}";
    fi

    #### Save old drivers (aka .o and .o.gz) in $d_usr
    # k is(are) the kernel version(s) extracted with sed from the full qualified
    # kernel module name(s) in file.list
    echo "Original drivers saved in /usr/local/share/%{name}";
    for k in $(sed 's/\/lib\/modules\/\([0-9a-zA-Z_\.\-]*\).*/\1/' $FL) ; 
    do
        d_drivers=/lib/modules/$k
        d_usr=/usr/local/share/%{name}/$k
        mkdir -p $d_usr
        cd $d_drivers; find . -name %{driver_name}.*o -exec cp --parents {} $d_usr \; -exec rm -f {} \;
        cd $d_drivers; find . -name %{driver_name}_*.*o -exec cp --parents {} $d_usr \; -exec rm -f {} \;
        cd $d_drivers; find . -name %{driver_name}.*o.gz -exec cp --parents {} $d_usr \; -exec rm -f {} \;
        cd $d_drivers; find . -name %{driver_name}_*.*o.gz -exec cp --parents {} $d_usr \; -exec rm -f {} \;
        cp --parents %{pciids} /usr/local/share/%{name}/
        if [ "%{pcitable}" != "/dev/null" ]; then
            cp --parents %{pcitable} /usr/local/share/%{name}/
        fi
    done

    # Add driver link
    for f in $(sed 's/\.new$//' $FL) ; do
        ln -f $f.new $f 
    done

    # Check if kernel version rpm was built on IS the same as running kernel
    BK_LIST=$(sed 's/\/lib\/modules\/\([0-9a-zA-Z_\.\-]*\).*/\1/' $FL)
    MATCH=no
    for i in $BK_LIST
    do
        if [ $(uname -r) == $i ] ; then
            MATCH=yes
            break
        fi
    done
    if [ $MATCH == no ] ; then
        echo -n "WARNING: Running kernel is $(uname -r).  "
        echo -n "RPM supports kernels (  "
        for i in $BK_LIST
        do
            echo -n "$i  "
        done
        echo ")"
    fi

    LD="%{_docdir}/%{name}";
    if [ -d %{_docdir}/%{name}-%{version} ]; then
        LD="%{_docdir}/%{name}-%{version}";
    fi

    #Yes, this really needs bash
    bash -s %{pciids} \
        %{pcitable} \
        $LD/pci.updates \
        $LD/pci.ids.new \
        $LD/pcitable.new \
        %{name} \
    <<"END"
    #! /bin/bash
    # $1 = system pci.ids file to update
    # $2 = system pcitable file to update
    # $3 = file with new entries in pci.ids file format
    # $4 = pci.ids output file
    # $5 = pcitable output file
    # $6 = driver name for use in pcitable file

    exec 3<$1
    exec 4<$2
    exec 5<$3
    exec 6>$4
    exec 7>$5
    driver=$6
    IFS=

    # pattern matching strings
    ID="[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]"
    VEN="${ID}*"
    DEV="   ${ID}*"
    SUB="       ${ID}*"
    TABLE_DEV="0x${ID}  0x${ID} \"*"
    TABLE_SUB="0x${ID}  0x${ID} 0x${ID} 0x${ID} \"*"

    line=
    table_line=
    ids_in=
    table_in=
    vendor=
    device=
    ids_device=
    table_device=
    subven=
    ids_subven=
    table_subven=
    subdev=
    ids_subdev=
    table_subdev=
    ven_str=
    dev_str=
    sub_str=

    # force a sub-shell to fork with a new stdin
    # this is needed if the shell is reading these instructions from stdin
    while true
    do
        # get the first line of each data file to jump start things
        exec 0<&3
        read -r ids_in
        if [ "$2" != "/dev/null" ];then
        exec 0<&4
        read -r table_in
        fi

        # outer loop reads lines from the updates file
        exec 0<&5
        while read -r line
        do
            # vendor entry
            if [[ $line == $VEN ]]
            then
                vendor=0x${line:0:4}
                ven_str=${line#${line:0:6}}
                # add entry to pci.ids
                exec 0<&3
                exec 1>&6
                while [[ $ids_in != $VEN ||
                     0x${ids_in:0:4} < $vendor ]]
                do
                    echo "$ids_in"
                    read -r ids_in
                done
                echo "$line"
                if [[ 0x${ids_in:0:4} == $vendor ]]
                then
                    read -r ids_in
                fi

            # device entry
            elif [[ $line == $DEV ]]
            then
                device=`echo ${line:1:4} | tr [:upper:] [:lower:]`
                table_device=0x${line:1:4}
                dev_str=${line#${line:0:7}}
                ids_device=`echo ${ids_in:1:4} | tr [:upper:] [:lower:]`
                table_line="$vendor $table_device   \"$driver\" \"$ven_str|$dev_str\""
                # add entry to pci.ids
                exec 0<&3
                exec 1>&6
                while [[ $ids_in != $DEV ||
                     $ids_device < $device ]]
                do
                    if [[ $ids_in == $VEN ]]
                    then
                        break
                    fi
                    if [[ $ids_device != ${ids_in:1:4} ]]
                    then
                        echo "${ids_in:0:1}$ids_device${ids_in#${ids_in:0:5}}"
                    else
                        echo "$ids_in"
                    fi
                    read -r ids_in
                    ids_device=`echo ${ids_in:1:4} | tr [:upper:] [:lower:]`
                done
                if [[ $device != ${line:1:4} ]]
                then
                    echo "${line:0:1}$device${line#${line:0:5}}"
                else
                    echo "$line"
                fi
                if [[ $ids_device == $device ]]
                then
                    read -r ids_in
                fi
                # add entry to pcitable
                if [ "$2" != "/dev/null" ];then
                exec 0<&4
                exec 1>&7
                while [[ $table_in != $TABLE_DEV ||
                     ${table_in:0:6} < $vendor ||
                     ( ${table_in:0:6} == $vendor &&
                       ${table_in:7:6} < $table_device ) ]]
                do
                    echo "$table_in"
                    read -r table_in
                done
                echo "$table_line"
                if [[ ${table_in:0:6} == $vendor &&
                      ${table_in:7:6} == $table_device ]]
                then
                    read -r table_in
                fi
                fi
            # subsystem entry
            elif [[ $line == $SUB ]]
            then
                subven=`echo ${line:2:4} | tr [:upper:] [:lower:]`
                subdev=`echo ${line:7:4} | tr [:upper:] [:lower:]`
                table_subven=0x${line:2:4}
                table_subdev=0x${line:7:4}
                sub_str=${line#${line:0:13}}
                ids_subven=`echo ${ids_in:2:4} | tr [:upper:] [:lower:]`
                ids_subdev=`echo ${ids_in:7:4} | tr [:upper:] [:lower:]`
                table_line="$vendor $table_device   $table_subven   $table_subdev   \"$driver\" \"$ven_str|$sub_str\""
                # add entry to pci.ids
                exec 0<&3
                exec 1>&6
                while [[ $ids_in != $SUB ||
                     $ids_subven < $subven ||
                     ( $ids_subven == $subven && 
                       $ids_subdev < $subdev ) ]]
                do
                    if [[ $ids_in == $VEN ||
                          $ids_in == $DEV ]]
                    then
                        break
                    fi
                    if [[ ! (${ids_in:2:4} == "1014" &&
                         ${ids_in:7:4} == "052C") ]]
                    then
                        if [[ $ids_subven != ${ids_in:2:4} || $ids_subdev != ${ids_in:7:4} ]]
                        then
                            echo "${ids_in:0:2}$ids_subven $ids_subdev${ids_in#${ids_in:0:11}}"
                        else
                            echo "$ids_in"
                        fi
                    fi
                    read -r ids_in
                    ids_subven=`echo ${ids_in:2:4} | tr [:upper:] [:lower:]`
                    ids_subdev=`echo ${ids_in:7:4} | tr [:upper:] [:lower:]`
                done
                if [[ $subven != ${line:2:4} || $subdev != ${line:7:4} ]]
                then
                    echo "${line:0:2}$subven $subdev${line#${line:0:11}}"
                else
                    echo "$line"
                fi
                if [[ $ids_subven == $subven  &&
                      $ids_subdev == $subdev ]]
                then
                    read -r ids_in
                fi
                # add entry to pcitable
                if [ "$2" != "/dev/null" ];then
                exec 0<&4
                exec 1>&7
                while [[ $table_in != $TABLE_SUB ||
                     ${table_in:14:6} < $table_subven ||
                     ( ${table_in:14:6} == $table_subven &&
                       ${table_in:21:6} < $table_subdev ) ]]
                do
                    if [[ $table_in == $TABLE_DEV ]]
                    then
                        break
                    fi
                    if [[ ! (${table_in:14:6} == "0x1014" &&
                         ${table_in:21:6} == "0x052C") ]]
                    then
                        echo "$table_in"
                    fi
                    read -r table_in
                done
                echo "$table_line"
                if [[ ${table_in:14:6} == $table_subven &&
                      ${table_in:21:6} == $table_subdev ]]
                then
                    read -r table_in
                fi
                fi
            fi

            exec 0<&5
        done

        # print the remainder of the original files
        exec 0<&3
        exec 1>&6
        echo "$ids_in"
        while read -r ids_in
        do
            echo "$ids_in"
        done

        if [ "$2" != "/dev/null" ];then
        exec 0>&4
        exec 1>&7
        echo "$table_in"
        while read -r table_in
        do
            echo "$table_in"
        done
        fi

        break
    done <&5

    exec 3<&-
    exec 4<&-
    exec 5<&-
    exec 6>&-
    exec 7>&-

    END

    mv -f $LD/pci.ids.new  %{pciids}
    if [ "%{pcitable}" != "/dev/null" ]; then
    mv -f $LD/pcitable.new %{pcitable}
    fi

    uname -r | grep BOOT || /sbin/depmod -a > /dev/null 2>&1 || true

    ########################### end RPM installation section

    ########################### begin RPM deinstallation section
    %preun
    # If doing RPM un-install
    if [ $1 -eq 0 ] ; then
        FL="%{_docdir}/%{name}-%{version}/file.list
            %{_docdir}/%{name}/file.list"
        FL=$(for d in $FL ; do if [ -e $d ]; then echo $d; break; fi;  done)

        # Remove driver link
        for f in $(sed 's/\.new$//' $FL) ; do
            rm -f $f
        done

        # Restore old drivers
        if [ -d /usr/local/share/%{name} ]; then
            cd /usr/local/share/%{name}; find . -name '%{driver_name}.*o*' -exec cp --parents {} /lib/modules/ \;
            cd /usr/local/share/%{name}; find . -name '%{driver_name}_*.*o*' -exec cp --parents {} /lib/modules/ \;
            rm -rf /usr/local/share/%{name}
        fi
    fi

    %postun
    uname -r | grep BOOT || /sbin/depmod -a > /dev/null 2>&1 || true

    ########################### end RPM deinstallation section

    #### end e1000e.spec

=closetwisty

=head3 Create the Customization Key for the e1000e Driver, Example for x86_64

Go to the customization key directory for SL5.1 and create the basic
files.

    # cd /afs/psi.ch/software/linux/dist/scientific/51/kickstart/custom/
    # mkdir e1000e
    # cd e1000e
    # touch custom.sh
    # vi custom.sh

=opentwisty

    #!/bin/bash
    # 
    # KS Customization for e1000e driver
    #
    # marc.gasser@psi.ch
    # 2009-02-24
    #
    # KSII scriplet rules apply
    #
    # This customization was added for the Intel Gigabit ethernet
    # card 82567LM, which comes with the new Fujitsu Siemens computers
    # Celsius W370, Esprimo p7935 e80, Esprimo e7935 e80 and Lifebook e8420,
    # because the e1000e.ko version 0.2.0 coming with SL kernels <= 2.6.18-92.1.22.el5
    # does not support this kind of hardware.
    #
    ##############################################################
    # Changelog:
    # ---------
    #
    ##############################################################

    ARCH=$(uname -m)
    DIR_E1000E=/mnt/master/linux/dist/scientific/51/psi/all

    # Install the kernel-module-e1000e containing the e1000e driver
    if test "$ARCH" = "x86_64"
    then
        echo "Install kernel-module-e1000e for $ARCH" >> $POSTLOG 2>&1
        rpm -ivh $DIR_E1000E/kernel-module-e1000e-2.6.18-92.1.22.el5-0.4.1.7-1.x86_64.rpm || \
            echo error installing kernel-module-e1000e \
            >> $POSTLOG 2>&1
    else
        echo "Install kernel-module-e1000e for $ARCH" >> $POSTLOG 2>&1
        rpm -ivh $DIR_E1000E/kernel-module-e1000e-2.6.18-92.1.22.el5-0.4.1.7-1.i386.rpm || \
            echo error installing kernel-module-e1000e \
            >> $POSTLOG 2>&1
    fi

=closetwisty

Copy the kernel-module-e1000e RPMS to F</mnt/master/linux/dist/scientific/51/psi/all/>
and F</mnt/master/linux/dist/scientific/51/kernel/all/>, create the symbolic links
in the corresponding F<current> and/or F<testing> repositories, and run C<createrepo>
within F<current> and/or F<testing>.

That's it. Now you can test the installation using the custom key
F<e1000e>.