Archive for 27 January 2009

Ubuntu – ancient African word meaning “I can not install Debian”.

From someone’s signature.

So we got that once again. Thousands of people got offline, because they do not want to use braindead official ICQ clients, while ICQ does not want to service anything better.

Maybe enough is enough?

There is an internet standard on instant messaging, called jabber.

Most likely, you already have both jabber account and jabber client.

You are unaware that you already have a jabber account? Well, at least you have one if you are registered at either Google Mail or LiveJournal. Yes, both Google Talk and LJTalk are actually implementations of jabber. If you don’t use these services, you may get an account on some jabber server – here is a list. Or you may run your own server.

You are unaware that you already have a jabber client? Well, at least if you are using Miranda, or QIP, or Pidgin, or Kopete – you do. All those do include jabber support. As well as many other instant messaging programs.

Or are you using ICQ because your contacts do? Well… not so long ago I’ve seen a very funny situation. Two technical persons working for different companies had to exchange some technical documents. Both perons have been used to Open Office and preferred to use that excellent package, and it’s standard OpenDocument format. However, both converted the document to Microsoft’s .doc, suffering a lot from formatting breakages, just to make it readable for the other side.

You guess the analogy?

Your contacts still use ICQ (if they really do) for only one reason – because you still use it. Similar to you using ICQ because they do. So just break the chain! For a short period when somebody will talk with you over ICQ, a jabber-to-icq transport will do the job. The above server list mentions some.

You don’t need ICQ. Nobody does. So just stop it. Now. And forever. You will make the world better by that simple step!

Are you aware of git add --patch? If not yet, here is a must-read article.

As a side note, adding gitready.com to your feed reader could be a good idea.

After switching my home systems from ru_RU.KOI8-R to ru_RU.UTF-8 locale, I suddenly found that I can’t read russian file names in CDs from my video collection. Tried to play with iocharset mount option, but with zero result.

After a hint from a helpful person, I found that I have to mount with -o norock,utf8 to see russian filenames.

Don’t know what sort of breakage it is. Probably I did something wrong when writing the CDs (more than 5 years ago, using cdrecord from command line).

To make KDE+HAL to mount CDs with -o norock, I had to add a line for /dev/scd0 to /etc/fstab.

When you use perl or similar scripting language, and use variable to store command-line parameter, and then test that variable to check if parameter was passed or not, beware of

if ($param) {
    ... #param was passed
}

Think what happens if $param is “0″ string. And use if (defined($param)) instead.

That happened to be the reason why dpkg-buildpackage ignored -v0 flag. And when you discover that through pdebuild that does not process --debbuildopts “-sa -v0″ properly, you will first think that pdebuild once again has issues with passing multiple arguments to underlying tools, and spend your time looking in wrong direction…

Quick instructions

  • Install qemubuilder package, version 0.48 or newer.
  • Grab kernel image from here.
  • Create a configuration file for qemubuilder, using following template:
    ARCH=armel
    MEMORY_MEGS=256
    KERNEL_IMAGE=$DIR/vmlinuz-2.6.26-versatile-qemu
    BASEPATH=$DIR/base.qemu
    MIRRORSITE=$MIRROR
    BUILDPLACE=$DIR/build
    BUILDRESULT=$DIR/result

    Replace $DIR with a full path to some directory, and $MIRROR with your debian mirror. Create empty directories $DIR/build and $DIR/result.

  • Ensure that your /etc/resolf.conf file contains a proper nameserver line that points to a working DNS server (and not to 127.0.0.1 – that won’t work inside qemu environment).
  • Run
    sudo qemubuilder --config $DIR/config --create

    ($DIR/config is the path to your qemubuilder configuration file)

  • Bind-mount just-created $DIR/base.qemu:
    mkdir $DIR/mnt
    mount -o loop $DIR/base.qemu $DIR/mnt
  • Edit $DIR/mnt/pbuilder-run file and ensure that it properly mounts all pseudo-filesystems:
    ...
    mount -n proc /proc -t proc
    mount -n sysfs /sys -t sysfs
    mount -n devpts /dev/pts -t devpts
    ...
  • Create $DIR/mnt/etc/apt/apt.conf.d/20no-pdiffs file with the following line:
    Acquire::PDiffs "false";

    This disables pdiffs – those are terribly slow inside qemu. If you are traffic- or bandwidth-limited, better to set up local apt-cacher.

  • Unmount $DIR/base.qemu:
    umount $DIR/mnt

That’s all. Now you can build binary-armel packages using

sudo qemubuilder --config $DIR/config --build filname.dsc

Read man pbuilder for build options. Also don’t forget to run

sudo qemubuilder --config $DIR/config --update

sometimes to keep your build environment up to date.

Long story

I own a Neo Freerunner device. Being a (unfortunately not very active) Debian Developer, I naturaly want to run and enhance Debian on Freerunner.

I’m going to build debian packages for Freerunner. To do that correctly, a clean build environment is required. For native backage builds, such an environment is provided by pbuilder package. To cross-build packages for armel archutecture, qemubuilder should provide the same.

I found some initial instructions to set up qemubuilder on DebianOnFreeRunner Debian Wiki page. It suggested to use debian-installer versatile netboot kernel with qemu. That did not work for me:

VFS: Unable to mount root fs on unknown-block(0,0)

I thought that proper driver may be inside initrd, and tried to use initrd image from the same URL. That also did not work – this time with

/init: exec: line 20: /pbuilder-run: not found

At this moment I asked for an advice in the smartphones-userland mailing list, and got a reply suggesting to use kernel from here. With this kernel (and initrd) things became better a bit – debootstrap second stage completed inside qemu. But then it failed again, being unable to reach network to install build-essential. It tried to load network driver with modprobe, but that could not work because debootstrap does not install any kernel modules into the target image.

Next attempt was to make debootstrap to include linux-image-2.6.26-1-versatile package. For that, debootstrap provides --include command-line option. But how to pass it to debootstrap called from qemubuilder --create? I looked into qemubuilder sources and found that debootstrap command-line is hardcoded. Not good. I fooled it by creating /usr/local/sbin/debootstrap containing

exec /usr/sbin/debootstrap --include=linux-image-2.6.26-1-versatile "$@"

That failed again, this time because of debootstrap second stage being unable to unpack packages. Bind-mounted qemu’s filesystem to the host, looked inside /debootstrap/debootstrap.log there, and found

Unpacking linux-image-2.6.26-1-versatile (from .../linux-image-2.6.26-1-versatile_2.6.26-12_armel.deb) ...
Ok, Aborting, since the bootloader might not handle an initrd/initramfs image.
dpkg: error processing var/cache/apt/archives/linux-image-2.6.26-1-versatile_2.6.26-12_armel.deb (--unpack):
 subprocess pre-installation script returned error exit status 1

This could be likely fixed by putting do_initrd = yes into /etc/kernel-img.conf, but how to make qemubuilder to do that? I did not want to change qemubuilder’s C source this time.

Also, I recognized a more generic problem. Kernel image and kernel modules must exactly match each other. Because of that, using whatever external kernel to boot qemu, while using debian’s kernel-image package to provide modules, is a broken design – simply because it’s unclear how to keep those two in sync.

Using debian’s kernel-image to provide all components does not look good, because debian’s kernel makes hard use of initrd, and initrd image is not included into the package (it is built during package installation). So to take all components from debian’s kernel-image to provide, one needs already-running debian armel system to build initrd. Although possible with downloadable images, this does not look good to me.

So I decided to build a kernel that will work with qemubuilder without any modules, and make that available to whoever needs it.

To do so, I downloaded complete armel debian qemu installation from already mentioned location, booted it, and did this:

apt-get install linux-source-2.6.26 build-essential ncurses-dev
tar xjf /usr/src/linux-source-2.6.26
cd linux-source-2.6.26
cp /boot/config-2.6.26-1-versatile ./.config
make menuconfig

Starting with debian’s default configuration, I wanted to build disk, filesystem, and network drivers into the kernel. I typed lsmod on another virtual console, and found that I need to switch from M to * the following options:

  • SCSI device support (under Device drivers : SCSI support)
  • SCSI disk support (under Device drivers : SCSI support)
  • SYM53C8XX Version 2 SCSI support (under Device drivers : SCSI support : SCSI low-level drivers)
  • SMC 91C9x/91c1xxx support (under Device drivers : Network drivers : Ethernet (10 or 100 Mbit)
  • Ext3 journalling file system support (under File systems)

Resulting kernel configuration file is here, and compiled kernel image is here.

With this kernel things work much better: both qemubuilder --create and qemubuilder --update complete successfully (but only if host /etc/resolv.conf is ok – while running qemubuilder --create , /etc/resolv.conf file is copied from host to the qemu filesystem, so that file should contain nameserver line(s) that will be valid within qemu, in particular not point to 127.0.0.1).

My first attempts to build binary-armel packages failed – qemu hanged after installing build-depends. After some experiments, found that it may be fixed by ensuring that all pseudo-filesystems are mounted – see above for instructions.