Archive for December, 2007

Terry Pratchett: The Carpet People

Monday, December 17th, 2007

En ung Terry Pratchett skrev “The Carpet People” før han laget Discworld-bøkene, men man gjenkjenner mange elementer fra de senere bøkene her, og fra genrens bestefar. En stor, flat verden (nede i et teppe) med et mytologisk overbygg i en middelalderaktig tid. Handlingen er komprimert, med klassiske fantasy-ingredienser i rask rekkefølge: Den unge høvdingsønnen som tenker mer enn han slåss viser seg å være et duganes lederemne. Et vandringsfølge med et oppdrag. En vismann viser veien. Underlige, litt overjordiske skapninger som ser framtid og fortid er ikke så glade i å gi råd, men gir dem likevel. En vandringsmann som slår følge viser seg å være en stor kriger og potensiell kandidat for tronen. Onde menneskeliknende skapninger prøver å ta herredømme over det gode riket. En hemmelig gang under jorda (teppet), før de blir tatt til fange, men selvsagt rømmer igjen. Krigerstammer på vandring blir gode allierte i det store slaget på slutten. Høres det ikke veldig kjent ut? Joda, men det blir riktig bra selv om oppskriften er kjent. Pratchetts småhysteriske humor er i ferd med å springe ut, og krydrer med gapskratt innimellom. En riktig godbit. Anbefales for fantasy-elskere med glimt i øyet.

Build a RHEL5 kernel using a custom configuration

Friday, December 14th, 2007

From time to time, RedHat’s predefined kernel configuration does not suit your needs. You may want to disable or enable drivers that are not in the stock config, or you may want to build more specialized kernels. But you want to keep the build framework and all the patches. Here’s a short howto. With small changes, it works on RHEL4 as well. In Fedora, the build framework has become a bit more mature, with more options and less editing of files. You can find their corresponding document at http://fedoraproject.org/wiki/Docs/CustomKernel.

In the following you may replace “i686″ and “i386″ for “x86_64″ if you have an AMD64 or EM64T cpu on your target system. Run the following on a build system. If you are of the more clever users (you are reading this, right?), you’ll replace /usr/src with your private rpm build space, see http://users.linpro.no/ingvar/rpm.html.

  • Download kernel-2.6-something.src.rpm from RHN
    Surf to https://rhn.redhat.com/
    -> Channels
    -> Red Hat Enterprise Linux Server 5
    -> IA-32 (i386)
    -> Packages
    -> Filter by Package: kernel -> Go
    -> kernel-some-version
    -> Download Source Package

  • Install the source package you just downloaded into your rpm build space
    rpm -ivh kernel-2.6-something.src.rpm
  • Install build dependencies
    yum install ncurses-devel kernel-devel make gcc
  • Unpack source code to get access to the configuration files
    cd /usr/src/redhat/SPECS
    rpmbuild -bp --target=i686 kernel-2.6.spec
  • Pick a starting point configuration, for example, stock i686
    cd /usr/src/redhat/SOURCES
    find . -name kernel\\*config
    cp kernel-2.6.18-i686.config kernel-2.6.18-i686.config.orig
    cp kernel-2.6.18-i686.config /usr/src/redhat/BUILD/kernel-2.6.18/linux-2.6.18.i686/.config
  • Make your local configuration changes
    cd /usr/src/redhat/BUILD/kernel-2.6.18/linux-2.6.18.i686
    make oldconfig
    make menuconfig
  • RedHat’s build system needs a commented line in the top of the config file with the target system’s generic architecture platform
    vi .config

    Enter line on the top with a ‘#’ followed by a space and the output of the command ‘uname -i’ on the target system. For, for example, a 32bit intel box, the top line of .config should read:

    # i386
    

    Then copy the file back to the SOURCES directory

    cp .config /usr/src/redhat/SOURCES/kernel-2.6.18-i686.config
  • Configure what kernel variants you want to build. Also add a local identifier in the release field, so you don’t match an existing kernel.
    cd /usr/src/redhat/SPECS
    vi kernel-2.6.spec

    Change the following lines, unless you need extra packages like xen, doc, pae, or kernel-headers. Search for lines that look the ones below. Do not enter new tags. Instead of “local”, you may write anyhting you want in the release tag.

    %define buildxen 0
    %define builddoc 0
    %define buildkdump 0
    %define buildheaders 0
    
    %define release 8.1.15.local%{?dist}
    
    %ifarch i686
    %define buildpae 0
    
  • Build the kernel. This may take 10 minutes, or 2 hours, depening on your build system cpu/memory, and how many kernel packages you are building.
    time rpmbuild -bb --target=i686 kernel-2.6.spec
  • Associative arrays in bash

    Tuesday, December 4th, 2007

    If you do a google search for “associative arrays in bash”, you get a lot of hits that tell you that this is a feature not found in bash (though later versions may include this). Now, I find associative arrays (or hash tables if you like) a very nice feature to have available. And it is not that hard to emulate it in bash. One can use two arrays, one for the keys, and the other for the data elements, and a common counter for the indexes. A more ugly, but faster design could be direct string to variable name translation, with eval doing the dirty work.

    Note that this kind of translation may be called seriously bad design, and in an interactive script, it may lead to serious security flaws. But if you know what the strings will look like, this short hand may do the work for you.

    Consider the following code snippet:

    
    #!/bin/bash
    #
    # Associative arrays in bash, take 1
    # Using simple translation with eval
    
    # Some test values with doublettes
    values="a a a a b b c d";
    
    # The incrementer for the keys to the array
    key=-1 # Start with off-by-one, as incrementing is the first step in the loop
    
    for val in $values; do
    
        # Need to check for uninitialized value, to get rid of doublettes
        # (and yes, here test(1) needs the extra character in the test)
        if eval [ 'x$'$val = "x" ]; then
            ((key++))
        fi
    
        # Now, fill the hash with values
        eval $val=$key;
        case $val in
            "a")
                arr[$key]="alice";
                ;;
            "b")
                arr[$key]="bob";
                ;;
            "c")
                arr[$key]="charlie";
                ;;
            "d")
                arr[$key]="diana";
                ;;
        esac
    done
    
    # Look up the value for a single key 'a'
    key="a"
    echo -n "Data entry for key $key is: "
    eval key="$"$key
    echo ${arr[$key]};
    
    # Print the contents of the array
    echo ""; echo "Whole array:"
    for (( key=0; key < ${#arr[*]}; key++ ))
    do
      echo ${arr[$key]}
    done
    
    ## EOF
    
    
    

    For more serious scripts, consider as mentioned, putting the keys in its own array, and search it while looking up values. This would take more time, though.

    #!/bin/bash
    #
    # Associative arrays in bash, take 2
    # Using two arrays

    # Some test values with doublettes
    values="a a a a b b c d";

    # Search for existing keys
    function getkey {
    key=$1
    for (( i=0; i < ${#keys[*]}; i++ )) {
    if [ "${keys[$i]}" = "$key" ]; then
    return $i
    fi
    }
    # Not found, create a new key
    keys[$i]=$key
    return $i
    }

    # Now, fill the hash with values
    for val in $values; do

    # First, get a new key
    getkey $val; key=$?

    case $val in
    "a")
    arr[$key]="alice";
    ;;
    "b")
    arr[$key]="bob";
    ;;
    "c")
    arr[$key]="charlie";
    ;;
    "d")
    arr[$key]="diana";
    ;;
    esac
    done

    # Look up the value for a single key 'd'
    echo -n "Data entry for key 'd' is "
    getkey 'd'; key=$?
    echo ${arr[$key]};

    # Print the complete contents of the hash
    echo ""; echo "Whole hash:"
    for (( i=0; i < ${#arr[*]}; i++ ))
    do
    echo -n "%arr{"
    echo -n ${keys[$i]}
    echo -n "}="
    echo ${arr[$i]}
    done

    # EOF