Fixing the Flash ‘blue people’ bug

If you watch YouTube videos on Linux, you may have noticed that they’ve all had a blue tint lately, and that videos sometimes ‘leak’ through other windows. This is due to a bug in the latest version of Flash player which presents itself when using NVIDIA’s binary driver. Although the bug has been confirmed to be in Flash itself rather than the NVIDIA driver, it’s doubtful that Adobe will ever release a fix as they seem to have pretty much given up on Linux. Fortunately, you can work around this problem by recompiling libvdpau with a patch made by Stephen Warren.

To do this on Slackware, first head over to SlackBuilds.org and grab the latest libvdpau SlackBuild (but don’t bother downloading the actual source archive just yet). Extract the SlackBuild archive as usual:

tar -xvf libvdpau.tar.gz
cd libvdpau

Next, you’ll need to get hold of Stephen Warren’s patch, which can be found at here. Copy and paste everything from the “Signed-off-by:” line to the end of the message into a text file and save it into the libvdpau directory as flash_patch.patch.

The reason you didn’t download the source archive from SlackBuilds.org is that this patch applies to a later version of the code which is presently only available in the Git respository. You can download this as a tar archive here. Save this into the libvdpau directory and give it a more sensible name:

tar -xvf libvdpau-4262513e67c3572ed19bd796ec6180cdde7ccb7e.tar.gz
mv libvdpau-4262513e67c3572ed19bd796ec6180cdde7ccb7e libvdpau-20110816
tar -cvzf libvdpau-20110816.tar.gz libvdpau-20110816

Now edit libvdpau.SlackBuild to update the version number and apply the patch. Change VERSION=0.4.1 (or similar) to VERSION=20110816 and add the following commands right before ./configure is executed:

patch -p1 < "$CWD/flash_patch.patch"
./autogen.sh --prefix=/usr --sysconfdir=/etc

You should also remove ChangeLog from the list of documentation files towards the bottom of the SlackBuild script, as this file doesn’t exist in the Git version of libvdpau. Finally, run the SlackBuild as usual and if all goes well you’ll end up with a Slackware package in /tmp that you can upgrade your existing version to:

./libvdpau.SlackBuild
upgradepkg /tmp/libvdpau-20110816-x86_64-1_SBo.tgz

I didn’t even have to restart X, simply restarting my web browser was enough to get YouTube back to normal!

Slackware certwatch warning

This morning I logged into my Slackware box to find the following email waiting for me:

    WARNING: certificate /etc/ssl/certs/ca-certificates.crt
    is about to expire in time equal to or less than 7 days from now on,
    or has already expired - it might be a good idea to obtain/create new one.

    NOTE: This message is being sent only once.

    A lock-file
    /var/run/certwatch-mailwarning-sent-ca-certificates.crt
    has been created, which will prevent this script from mailing you again
    upon its subsequent executions by crond. You dont need to care about it;
    the file will be auto-deleted as soon as you'll prolong your certificate.

The ca-certificates.crt file is a bundle containing CA certificates, just like the one’s included in web browsers, which are used to establish the authenticity of SSL connections. The certificates themselves are provided by the ca-certificates package and are stored in /usr/share/ca-certificates. The ca-certificates.crt bundle, along with a host of symlinks in /etc/ssl/certs, is generated by the update-ca-certificates program which runs automatically when ca-certificates is installed. This program looks in the configuration file /etc/ca-certificates.conf for a list of certificates to include.

The warning that ca-certificates.crt is about to expire is generated by certwatch, a daily cron job, and is due to the fact that the first certificate in the bundle expires on 30 November. This corresponds with the first certificate listed in ca-certificates.conf, namely /usr/share/ca-certificates/brasil.gov.br/brasil.gov.br.crt. You can see the expiration date of this certificate with the following openssl command:

openssl x509 -in /usr/share/ca-certificates/brasil.gov.br/brasil.gov.br.crt -noout -enddate

In my opinion, certwatch shouldn’t be checking ca-certificates.crt. Its purpose is to warn the system administrator about their own certificates (used to secure a web server, for example) that are about to expire, so that he can renew them before they do. However, the certificates contained in ca-certificates.crt belong to CAs and therefore it is not the system administrator’s job to renew them. What’s more, they are provided by the ca-certificates package, so if any changes (or removals) are required then these should come in the form of an updated package. If you want to ‘fix’ certwatch to stop it from checking this file, simply look for the following line in /etc/cron.daily/certwatch…

find $CERTDIR -type f -maxdepth 1 | while read certfile ; do

…and change it to:

find $CERTDIR -type f -maxdepth 1 ! -name ca-certificates.crt | while read certfile ; do

As the email says, certwatch saves a lock file, so even if you do nothing you will only receive this warning once (until another certificate expires). If you want to remove the expiring certificate yourself, however, you can do so by commenting out its line in /etc/ca-certificates.conf and then running:

update-ca-certificates --fresh

Making a dual-architecture Slackware USB stick

Slackware comes with a handy tool to create a bootable USB stick containing the Slackware installer and packages. I thought it would be nice to have one containing both the 32-bit and 64-bit versions of Slackware. With a little bit of work, this can be done.

To do this yourself, you’ll need local copies of the Slackware and Slackware64 trees, plus a blank USB stick (or one that you don’t mind erasing). A 4GiB stick is large enough to hold both architectures of Slackware 13.37, minus the source code and a couple of other bits and bobs. All of the commands below should be run as root.

For the rest of this guide, I’m going to assume that you have the Slackware and Slackware64 trees mounted under /mnt, in the directories slackware-13.37 and slackware64-13.37 respectively. You can use a location other than /mnt if you wish, but the directory names must be the same for this to work. You could use the Slackware DVDs, or rsync the trees from a Slackware mirror, but personally I loopback-mounted the ISO images like so:

mkdir -p /mnt/{slackware{,64}-13.37}
mount -o loop slackware-13.37-install-dvd.iso /mnt/slackware-13.37
mount -o loop slackware64-13.37-install-dvd.iso /mnt/slackware64-13.37

Next, we’ll use the bundled tool to create a Slackware (32-bit) bootable USB stick:

sh /mnt/slackware-13.37/usb-and-pxe-installers/usbimg2disk.sh -f -o /dev/sdb -s /mnt/slackware-13.37

Replace /dev/sdb with the device name of your USB stick. The script will display some information relating to this device and give you a chance to back out if you chose the wrong one. Be very careful here, or you could end up accidentally formatting a hard disk.

Once the script has finished, the next step is to copy the kernel, initrd and packages from the Slackware64 tree to your USB stick. First, mount the USB stick under /mnt/usb and copy across the 64-bit kernel.

mkdir -p /mnt/usb
mount /dev/sdb1 /mnt/usb
cp -a /mnt/slackware64-13.37/kernels/huge.s/bzImage /mnt/usb/syslinux/huge64.s

I call this huge64.s so that it doesn’t overwrite the 32-bit huge.s kernel already on the USB stick.

The initrd needs to be modified slightly to make the Slackware installer automatically mounts the USB stick and uses it as the default installation source. The following commands will extract the Slackware64 initrd.img, make the appropriate changes, and put the rebuilt copy onto your USB stick:

mkdir -p /tmp/initrd
cd /tmp/initrd
gunzip -cd /mnt/slackware64-13.37/isolinux/initrd.img | cpio -i -d -H newc --no-absolute-filenames
mkdir usbinstall
echo "mount -t vfat -o ro,shortname=mixed \$(/sbin/blkid -t LABEL=USBSLACKINS | cut -f1 -d:) /usbinstall 1>/dev/null 2&1" >> etc/rc.d/rc.S
sed -i -e 's# --menu# --default-item 6 --menu#' usr/lib/setup/SeTmedia
sed -i -e "s# 2> \$TMP/sourcedir# /usbinstall/slackware64-13.37/slackware64 2> \$TMP/sourcedir#" usr/lib/setup/INSdir
FIXF=$(find usr/lib/setup -name SeTp*media)
sed -i -e 's# --menu# --default-item 3 --menu#' $FIXF
chmod 0755 /tmp/initrd
find . |cpio -o -H newc |gzip > /mnt/usb/syslinux/initrd64.img
rm -rf /tmp/initrd

(This is heavily based on the usbimg2disk.sh script itself, so thanks go to Eric Hameleers.)

Next, copy the Slackware64 tree on to your USB stick, with a few exclusions to save space:

rsync -rpthDL --delete --exclude=source --exclude=extra/aspell-word-lists --exclude=isolinux --exclude=usb-and-pxe-installers --exclude=pasture /mnt/slackware64-13.37 /mnt/usb

Add the following lines to /mnt/usb/syslinux/syslinux.cfg to allow booting the 64-bit kernel and initrd:

label huge64.s
  kernel huge64.s
  append initrd=initrd64.img load_ramdisk=1 prompt_ramdisk=0 rw printk.time=0 SLACK_KERNEL=huge.s

Finally, unmount the USB stick and do some tidying up:

umount /mnt/{slackware{,64}-13.37,usb}
rmdir /mnt/{slackware{,64}-13.37,usb}

You should now be able to boot from your USB stick. At the syslinux boot prompt, either hit enter for the 32-bit installer, or enter huge64.s for the 64-bit installer. If you wish, you can edit the f2.txt and message.txt files in the syslinux directory to remind you of this.

Booting Slackware from a virtio hard disk in a KVM virtual machine

Although I run Slackware as my main desktop OS, I also have it installed in a KVM virtual machine. This is very useful for package building: By careful use of cloning, I can be sure that I always have a fresh install to hand, and therefore my packages won’t accidentally pick up any unnecessary dependencies that may be present on my main system.

Unfortunately, if you use virtio for your KVM hard disks (which you should for maximum performance) getting Slackware to boot isn’t quite straightforward. The following guide describes how I made this work. I hope it saves someone some time.

Install Slackware as you normally would, but remember when partitioning that your first hard disk will be /dev/vda instead of /dev/sda. When you choose to install lilo to the MBR, you will see the following message:

Fatal: open /dev/sda: No such device or address

Don’t worry about this for now. Continue to the end of setup, then choose EXIT to drop to the shell, but don’t reboot just yet. There are a couple more steps that must be taken to make your new Slackware installation bootable.

The partition containing Slackware will already be mounted under /mnt, so you can chroot into this to perform the necessary configuration. Don’t forget to bind mount /dev to /mnt/dev first, as lilo requires access to this:

mount -obind /dev /mnt/dev
chroot /mnt

The default Slackware kernel (even the huge one) doesn’t include the modules required to boot from a virtio hard disk, so these must be added to an initrd. Copy the sample mkinitrd.conf file and open it in an editor:

cd /etc
cp mkinitrd.conf.sample mkinitrd.conf
vi mkinitrd.conf

Find the following lines:

#MODULE_LIST="ext4"
#ROOTFS="ext3"
#ROOTDEV="/dev/sda1"

Replace them with:

MODULE_LIST="ext4:virtio_blk:virtio_pci"
ROOTFS="ext4"
ROOTDEV="/dev/vda1"

(Assuming of course that your root filesystem is /dev/vda1 and this is formatted as ext4.) Then create the initrd with:

mkinitrd -F

Next, add this initrd to your lilo configuration. Open up /etc/lilo.conf and find the lines:

image = /boot/vmlinuz
root = /dev/vda1

Change these to:

image = /boot/vmlinuz
initrd = /boot/initrd.gz
#root = /dev/vda1

There’s one more change to make in lilo.conf, as described on the KVM wiki (http://www.linux-kvm.org/page/Boot_from_virtio_block_device). Find:

boot = /dev/sda

Change /dev/sda to /dev/vda and add the following line beneath it:

disk = /dev/vda bios=0x80 max-partitions=7

Now install lilo by executing:

lilo

It is recommended to run Slackware with the generic rather than the huge kernel for everyday use, and now that you’ve created an initrd, you should be able to do this. Simply update the symbolic links in /boot to point to the appropriate kernel:

cd /boot
rm System.map config vmlinuz
ln -s System.map-generic-* System.map
ln -s config-generic-* config
ln -s vmlinuz-generic-* vmlinuz

That’s it. Press Ctrl+Alt+Delete, cross your fingers, and if you’ve done everything right your virtual machine should boot into a shiny new Slackware.

Using rsync to provide progress bars when copying files

For anyone who likes to do their file management from the command-line in Linux, here’s a useful tip courtesy of Mattis Geniar.

The cp command is great for copying small files, but if you want to copy a large file which takes a bit of time, it doesn’t provide any indication of how it is progressing. Fortunately, the rsync command comes to the rescue.

I use rsync on my box to maintain local mirrors of a couple of FTP sites and also to backup configuration and other essential files. Synchronising files over a network is the typical use for rsync, so like me you may not have considered it for simple copying on a local filesystem, but there’s nothing to stop you from using it in this way, and the progress bars it can provide make this worthwhile. A typical command will look something like this:

rsync -av --progress SOURCE DEST

The -a flag stands for archive, and is analogous to the -a flag of cp. The -v flag increases verbosity, and –progress provides animated progress bars. You can always save some time by defining an alias in your ~/.bashrc. For example:

alias copy='rsync -av --progress'

Note that if you’re copying a directory, a trailing slash on the source argument is significant. Including the slash will copy the contents of the directory, whereas omitting it will copy the directory itself. See the rsync manpage if you are unsure.

Installing qemu-kvm and virt-manager on Slackware

I’ve been playing with KVM/QEMU virtualization this weekend. In particular, I wanted to get the virt-manager GUI up and running so I can have an easy to use environment for messing around with different operating systems. I had been using VirtualBox for this, but KVM is rapidly becoming the de facto standard for open source virtualization, and I’m not too keen on relying on Oracle software given the company’s apparent contempt for the free software community.

For those who don’t know, KVM is a Linux kernel module which provides access to the hardware virtualizaton features available on modern processors. QEMU is a processor emulator which can be used standalone, but recent versions are also able to harness the power of KVM to provide a significant speed boost. QEMU includes a set of command-line tools which are enough to get you up and running, but if you prefer a graphical interface, then you’ll need to install virt-manager as well.

Slackware users can get a binary qemu-kvm package from Alien Bob which is pretty much self-contained. You’ll need to add a kvm group to your system, and make sure any non-root users who you want to be able to use KVM are members of it. You’ll also need to ensure that the kvm kernel module, along with kvm_amd or kvm_intel depending on your CPU type, are loaded. I simply added the following to my /etc/rc.d/rc.local:

/sbin/modprobe kvm
/sbin/modprobe kvm_intel

Unfortunately Alien Bob doesn’t have a virt-manager package, but you can head over to SlackBuilds.org to get it and all of its dependencies. The main dependency of virt-manager is libvirt, which provides a daemon to which the GUI connects in order to control your virtual machines. Once you have everything installed, open up /etc/libvirt/libvirtd.conf and uncomment the following lines:

unix_sock_group = "libvirt"
unix_sock_rw_perms = "0770"

Next, create a libvirt group and add your users to it. Finally launch the libvirtd daemon:

libvirtd -f /etc/libvirt/libvirtd.conf -d

The libvirt package from SlackBuilds.org doesn’t include an RC script, so you’ll need to create your own, or simply add this command to /etc/rc.d/rc.local.

You should now be able to launch virt-manager and use the wizard to start creating your virtual machines. One last thing which took me a while to figure out: if virt-manager complains about KVM not being available, try creating a link from /usr/bin/kvm to /usr/bin/qemu-system-x86_64. Apparently, virt-manager looks for this file to determine whether KVM can be used, so if you don’t do this, you virtual machines will run without it and be much slower.

Are the French taking over time itself? Well, no.

At least, that’s what the Daily Mail would have you believe. I was reading an article on their website the other day which was in danger of being quite interesting, had it not been brimming with the usual anti-European vitriol, thinly disguised as good old-fashioned British patriotism.

The gist of the story is that we Brits invented modern timekeeping, and that’s why all the world’s time zones are given relative to GMT (Greenwich Mean Time), and the prime meridian (also known as zero degrees longitude) runs right through the Royal Observatory in Greenwich, London. This is pretty much true, although nowadays most time zones are legally defined as offsets from UTC, not GMT. But more on that later.

What the Mail takes issue with is a proposal by “[b]ureaucrats at the International Telecommunications Union in Geneva…to abandon GMT as the world’s standard time.” If successful, this would mean that “the new guardians of time will be the International Bureau of Weights and Measures” which happens to be based in, shock horror, Paris, France.

You see, the French are still smarting over the fact that a hundred years ago they were finally forced to abandon Paris Mean Time and recognise GMT as the benchmark against which every other clock is set. Obviously, this is all a conspiracy to wrestle control of time away from the English and transfer it to the French. By the Swiss. I’m confused.

Of course, nobody’s really trying to take control of anything, and the proposal is actually just a minor alteration to the system we already use. As I mentioned earlier, the majority of time zones are no longer linked to GMT, but something called UTC, which stands for Coordinated Universal Time (Temps Universel CoordonnĂ© in French). You may be wondering how UTC can stand for either of those things, and that’s intentional. They chose an arbitrary ordering of the three letters to avoid offending either country.

Anyway, GMT and UTC are more or less the same thing, but with a subtle difference. GMT, as the name suggests, is the mean solar time along the prime meridian. This means that when the sun reaches its highest point over Greenwich, it is noon GMT. (Actually, it isn’t quite so simple, but for our purposes we needn’t worry about that). When atomic clocks came along, the rotation of the Earth was found to be not quite as regular as previously thought, and the time as told by atomic clocks gradually began to drift away from the time as revealed by the position of the sun.

This posed a conundrum: should time be kept by the perfectly regular beats of an atomic clock, or the less than perfect rotation of the Earth? Eventually, a compromise was reached in UTC: an atomic time standard would be used, but leap seconds could be inserted or removed as needed to keep to within a second of GMT. This has the advantage that every second is exactly the same length, and the price we pay for this regularity is that once in a while a second must be either skipped or repeated.

The proposal by the International Telecommunications Union is to abandon leap seconds, and allow UTC to drift further away from solar time. There would still be occasional corrections, but instead of being a second every few years, they could be a minute every century or so. The rationale behind this is that making fewer adjustments reduces the likelihood of a mistake. I’m sure that there are a host of valid arguments to be made both for and against this proposal, but unfortunately the Daily Mail isn’t making one. After all, the atomic time standard upon which UTC is based (known as TAI, or International Atomic Time) is already overseen by, you guessed it, our Parisian friends at the International Bureau of Weights and Measures.

SlackBuilds.org Firefox search plugin

If you’re a Slackware user, then you are probably aware of SlackBuilds.org. As the name suggests, it is a repository for SlackBuild scripts, which automate the process of compiling software from source and creating a Slackware package from the resulting binaries.

I regularly find myself searching this site for new software to install on my Slackware system, so I decided to create a search plugin for Firefox to speed up the process. Here’s what I came up with:

<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
    <ShortName>SlackBuilds.org</ShortName>
    <Description>SlackBuilds.org Search</Description>
    <InputEncoding>UTF-8</InputEncoding>
    <Image width="16" height="16">data:image/gif;base64,R0lGODdhEAAQALMPAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//////yH5BAEAAAEALAAAAAAQABAAAwRQMMhJqw0g35r7nsARAp+ULVoJLGz4iUecXtlzPI9rwbg9UyLcLaej1Gy4DKKCWAwASOKByUL0DqjFUtJkDXorlnYyGLQ61e3kgBggYm11IAIAOw==</Image>
    <Url type="text/html" method="GET" template="http://www.slackbuilds.org/result/">
        <Param name="search" value="{searchTerms}"/>
        <Param name="sv" value="13.37"/>
    </Url>
    <SearchForm>http://www.slackbuilds.org/</SearchForm>
</SearchPlugin>

If you’d like to use this yourself, simply copy the code above into a file (say slackbuilds.xml) and place this in the ~/.mozilla/firefox/p6mu31gg.default/searchplugins directory. (Your path will contain something other than p6mu31gg.default, and there may not be a searchplugins directory already, in which case you can just create it.) Restart Firefox, and you should now be able to search SlackBuilds.org directly from the search box in the top-right corner. You’ll need to select the SlackBuilds.org plugin by clicking on the down arrow to the left of the search box. It’s even got a cute little Tux logo!

Making ntfs-3g the default in Slackware

I have a USB stick which I use to transport files between different computers. Unfortunately this includes some Windows boxes, so I initially formatted it as FAT32, which both Linux and Windows can read from and write to no problem. However, when I tried to copy a large file to it, I came across the filesystem’s 4GB limit.

To solve this problem I reformatted the stick as NTFS, Microsoft’s more up-to-date filesystem. Until relatively recently, most Linux distributions could only mount NTFS partitions read-only, but nowadays they can also write to them courtesy of ntfs-3g. This comes as a standard package in Slackware, but a simple mount command such as:

mount /dev/sdb1 /mnt

Will still mount the drive as read-only. You can explicitly tell mount to use ntfs-3g by passing a type argument:

mount -tntfs-3g /dev/sdb1 /mnt

However, there is an easy workaround that will make mount use ntfs-3g by default. All you have to do is create a symbolic link from /sbin/mount.ntfs to /sbin/mount.ntfs-3g:

cd /sbin
ln -s mount.ntfs-3g mount.ntfs

Now a standard mount command will suffice to mount an NTFS partition read-write.

Removing SSH keys from known_hosts

If you use SSH regularly, then most likely at some stage you will have come across a message like this:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

This dramatic warning is to inform you that the SSH key on the remote machine has changed since the last time you connected to it. If you are expecting this (for example, because you have just wiped and rebuilt the server) then it is probably safe to continue. Otherwise, it is possible that someone is attempting a man in the middle attack, and you should proceed with great caution.

The SSH client maintains a database of keys for machines it has previously connected to. This is stored under .ssh/known_hosts in your home directory. In order to proceed past the warning above, you must first remove the key for this host from the database. This can be done with the ssh-keygen tool:

ssh-keygen -R hostname

If you now try to connect again, you will see a different warning along these lines:

The authenticity of host 'hostname' can't be established.
RSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx.
Are you sure you want to continue connecting (yes/no)?

This means that the SSH client cannot find this host in its database, and therefore you should check the key fingerprint shown to make sure it matches the one actually on the server. This creates a chicken and egg scenario, as to do so you will need to be logged into the server; however, if you suspect that you might be the victim of a MITM, it is better to be safe than sorry. Assuming you have physical access to the machine’s console, you can use the following command to create a fingerprint of its SSH key:

ssh-keygen -l -f /etc/ssh_host_rsa_key

If the output of this command is the same as the fingerprint displayed by the SSH client, you can type yes to continue connecting to the server.