Kernel Mode Setting for some ATI GPUs breaks suspend/resume

Another Fedora post.

I ran into this bug in Fedora 10, and by looking at those bug reports, I was able to work around it. But I had forgotten all about that when I installed Fedora 11. So I'm writing this partly as a note for myself in case the bug still exists in Fedora 12.

The problem is that Fedora incorporates something called Kernel Mode Setting for ATI Radeon GPUs. KMS is a technology that gives the kernel more responsibility for managing the graphics hardware, rather than leaving it in the hands of the X sever. Unfortunately, there is a bug in the Radeon KMS support, at least for the Radeon Mobility X1400 chip in my Thinkpad T60. It will suspend, but the video never comes back during a resume.

The workaround is to disable KMS. This can be done by adding the nomodeset option to the kernel command line in /boot/grub/grub.conf. You'll need to reboot for this to take effect.

KMS is a worthwhile technology, if for no other reason than making the Fedora boot process much prettier. But with suspend working, I rarely have to watch the boot process, so its appearance is not a major concern for me.

(On a distantly related note, I see that the GGI/KGI project is still just about going. That takes me back a few years.)

1 comments

Fedora 11, netbooks, and using ext4 without a journal

Fedora 11 is out. One of the highlights of this release is ext4 support (the successor to ext3 as the mainstream filesystem in the Linux world). But Fedora 11 doesn't just support ext4. It really wants you to use ext4 &mdash in fact, the Live CD won't install to any other filesystem.

(This is because an install from the Fedora Live CD works simply by copying the ext4 filesystem image contained on the Live CD onto the target storage device, and then resizing it. This makes such installs astonishingly fast, faster than any other method I've seen to install a comparably complete Linux system. The downside is a lack of flexibility.)

I don't have too many reservations about using ext4 on my personal systems. But it did raise an issue when I came to upgrade my Acer Aspire One netbook. The model I have uses a 7.5GB SSD as its main storage. Given the price of the whole machine, it's a safe assumption that this SSD is a cheap part, without the same kind of sophisticated wear levelling algorithms that server SSDs have. But ext4 is a journaled filesystem, just like ext3. The journal is a small area of storage which gets written to for each filesystem transaction, so it's conceivable that it could wear out a region of the SSD. For this reason, netbooks that come with Linux pre-installed tend to use the ext2 filesystem, which isn't journaled. And when I had Fedora 10 installed on mine, I switched the filesystem from ext3 to ext2 for that same reason. ext3 uses similar on-disk structures to ext2, so this is a straightforward operation, but some of the new features in ext4 mean this kind of downgrade is not possible.

But there is a solution to this: ext4 has an unjournaled mode. You can remove the journal from an ext4 filesystem with the tune2fs command:

tune2fs -O ^has_journal /dev/sdXX

The only problem is that this feature was introduced fairly recently, and some tools have yet to catch up. In particular, the version of e2fsprogs currently in Fedora 11 won't read the UUIDs from such filesystems. And because the Fedora installer generates an /etc/fstab which identifies filesystems by UUID, if you just run the above command, the system can't find its root filesystem and so doesn't get very far through the boot process.

So what you need to do to disable journaling is boot from the Live CD, mount the system partition and any boot partition and edit /etc/fstab and /boot/grub/grub.conf to replace UUID references with old fashioned /dev/sdXX block device names. Then unmount it, run the tune2fs command above, and you should have a functional system without a journal.

Update: there is a comprehensive list of tips to customize Fedora 11 for SSD-based netbooks here. It explains in more detail how to remove the journal from an ext4 filesystem.

2 comments

Grains of rice on a chess board

Today I read an IBM advertisement in a magazine. The same text can be found on the IBM site here. It contains the following sentence:

Experts predict that by 2010, the amount of digital information will double every 11 hours.

Experts in what, I wonder?

1 comments

DUI.Stream and HTTP request pipelining

Today I read about DUI.Stream:

We call this technique MXHR (short for Multipart XMLHttpRequests), and we wrote an addition to our Digg User Interface library called DUI.Stream to implement it. Specifically, DUI.Stream opens and reads multipart HTTP responses piece-by-piece through an XHR, passing each chunk to a JavaScript handler as it loads.

But how is that fundamentally different from HTTP request pipelining, where an HTTP client sends a stream of HTTP requests without waiting for a response before issuing the next request? HTTP request pipelining was standardised in RFC2616 - HTTP/1.1 .

Well, one major difference is that Digg can allow all their users to take advantage of their technique today. Amazingly, HTTP request pipelining is still disabled by default in the current releases of Firefox. On the IE side, it has been enabled in IE 8.

I notice that the 10th birthday of RFC2616 is coming up in June. I wonder if we should all mark the occasion by enabling HTTP request pipelining, by upgrading our browsers, or by going to about:config and tweaking it manually.

2 comments

The grim reality of C

In the last few years, I haven't had cause to write much C code; just enough to stop me getting rusty. I remain very fond of the C programming language, and sometimes I find myself thinking that programming in C has its advantages, despite the need to pay attention to a few details that are not an issue in higher-level languages. Maybe C is not so bad. Maybe, if I had to tackle a project with the right set of requirements, I'd work in C again.

But coming into contact with C code can be like reading about surgery before anaesthetic: The unwelcome and painful realization that people had to live like that for so long, and that in some primitive parts of the world, they still do.

Although I don't get to write much C code, I do still regularly refer to C code written by others. But there's a depth of understanding of a language and its milieu that can only be gained by writing a significant amount of code in that language, or making significant changes to an existing project. Today, I've been doing the latter.

The project in question is a relatively successful open source project, of a non-trivial size (150k lines). The leaders and main contributors appear to be competent and experienced, and have made sensible design decisions. After a superficial review of the code, my response was quite positive. It adheres to a range of uncontroversial coding standards. It is consistently formatted. And it uses utility functions where appropriate to handle error prone tasks safely. In particular, it avoids the direct use of malloc and friends, and instead uses a set of helper macros and functions for allocation and deallocations of common data structures and arrays.

But after a few hours of working on this codebase, I began to realize that it is riddled with allocation and deallocation bugs. The helpers help, but not enough. The consequence of the smallest confusion over the ownership of some data structure is a memory leak.

I'm not going to name the project, because I continue to believe that its overall quality is very good, and that the developers have tried hard to get these issues right. What it brings home to me is a fact that I haven't been forced to face for a long time: while bad programmers can write bad code in any language, even good programmers find it hard to write good, bug-free code in C.

1 comments

USB pass-through with libvirt and KVM, part two

A recent post here discussed how to enable USB pass-through under libvirt. But the technique there only allowed devices to be added when a VM was next started; you couldn't connect devices to a running VM.

This is a fairly major limitation. At best, the need to restart the VM is inconvenient. At worst, it makes the use of a USB device impossible. The full use of many USB devices involves disconnecting and reconnecting them to a running machine.

Recent versions of QEMU (and so KVM) do in fact have support for this; it's just that libvirt doesn't expose it. The QEMU support involves marking USB devices (identified by a vendor/product ID pair) for autoconnect. QEMU will then listen for connection events from the host OS, and repond to connections from the relevant devices by signalling a connection of the pass-through device to an emulated USB hub within the VM.

When libvirt runs KVM/QEMU, it specifies the pass-through USB devices through command line options. So by introducing a wrapper script that rewrites the command line options, we can enable autoconnect under libvirt.

Note that you will need a recent version of the KVM userspace support for this to work. It works for me with kvm-84. kvm-74, as included in Fedora 10 and Ubuntu 8.10 is not recent enough.

Here is the script I use:

#!/bin/sh
exec /usr/bin/qemu-kvm `echo $* | sed 's|-usbdevice host:\([^ ]*\)|-usbdevice host:auto:*.*:\1|g'`

Note that different Linux distributions use slightly different names for the KVM/QEMU binary. /usr/bin/qemu-kvm above is correct for RHEL/Fedora systems; under Ubuntu, you should substitute /usr/bin/kvm.

Save the script as /etc/libvirt/qemu/qemu-kvm, and make it executable. With that in place, you need to tell libvirt to use it instead of the real KVM binary. Do that by editing the VM XML description as described in my previous post. You need to edit the //domain/devices/emulator entry to refer to the wrapper script, e.g.

<domain type='kvm'>
  <name>windowsxp</name>
  …
  <devices>
    <emulator>/etc/libvirt/qemu/qemu-kvm</emulator>
    …
  </devices>
</domain>

Restart the relevant VMs, and USB pass-through with autoconnect should now work.

It's tempting to ask why this functionality isn't built-in to libvirt. My impression is that they are aiming for something more ambitious: The ability to enumerate devices on the host and then selectively pass those through to running VMs. This will be good when it's done, it's just a shame that it isn't there yet.

3 comments

Blogging for The Man

I have a blog post up on the company blog. But it's not about work (well, not work work), so if you are one of my small band of regular readers here, you should take a look.

0 comments

Using USB pass-through under libvirt and KVM

Virtualization solutions typically include a feature called USB pass-through: making a USB device attached to the host machine appear directly as a USB device attached to a virtual machine. KVM, the fully open-source virtualization solution for Linux, can do USB pass-through. It inherits this feature from QEMU, which KVM incorporates to provide system and device virtualization (KVM proper is focused on processor virtualization, and runs in kernel space; QEMU runs in user space).

But there's a hitch: KVM is most often used via libvirt and virt-manager, which provide a virtualization management infrastructure and graphical user interface. libvirt has some support for USB pass-through; but virt-manager doesn't support it at all. So here's a guide to using the libvirt command shell to get to this feature. These instructions require somewhat recent versions of KVM (74 and up) and libvirt (0.4.4 and up).

You will need to hand-edit the XML documents that libvirt uses to describe virtual machine instances (domains, in libvirt terminology). You do this via virsh, the command shell included with libvirt. virsh is fairly spartan, though it does have a decent on-line help facility (accessed via the help command). Run virsh as root, and use the list command to see your VM instances and their names:

virsh # list --all
 Id Name                 State
----------------------------------
  - windowsxp            shut off

If list --all didn't show any VM instances, you should create some using virt-manager.

You can view the domain definition XML with the dumpxml command:

virsh # dumpxml windowsxp
<domain type='kvm'>
  <name>windowsxp</name>
  …
</domain>

The edit command will open the domain definition XML in an editor:

virsh # edit windowsxp
Edit the XML as desired
Domain windowsxp XML configuration edited.

Update: I recently noticed that the edit command only appeared in libvirt version 0.4.5. Some current editions of popular Linux distributions still have an earlier version. In that case, you can edit the XML domain definition files under /etc/libvirt/qemu directly, but you will need to restart libvirtd afterwards.

We want to edit this XML to add a hostdev element as documented here on the libvirt site. But first, you need to work out the USB vendor and product IDs for the relevant device. You can discover these by attaching the device and running /sbin/lsusb on the host. For example, here's the lsusb output on my laptop:

$ /sbin/lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 012: ID 0a5c:2110 Broadcom Corp. Bluetooth Controller
Bus 005 Device 003: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

The pairs of hexadecimal numbers on each line are the vendor and produce IDs. For example, the bluetooth controller has a vendor ID of 0a5c, and a product ID of 2110.

To forward that to my windowsxp VM, I edit the domain definition as follows:

<domain type='kvm'>
  <name>windowsxp</name>
  …
  <devices>
    …
    <hostdev mode='subsystem' type='usb'>
      <source>
        <vendor id='0x0a5c'/>
        <product id='0x2110'/>
      </source>
    </hostdev>
  </devices>
</domain>

Note that it's a good idea to prevent the host from using the device before attaching it to a VM. In this case, I made sure the bluetooth controller was not being used by removing the relevant kernel modules with rmmod. For USB storage devices, it's sufficient to make sure that they are not mounted by the host kernel. And for custom USB devices, without drivers in the Linux kernel, it won't try to do anything with them, so you're usually fine.

There are a couple of limitations to this USB pass-through support. The first is that the change won't take effect until you next start the VM. The second is that it only works if the USB device in question is connect at the time you start the VM. That's quite a serious restriction. It's often convenient, and sometimes necessary, to be able to connect a device to, and disconnect it from, a running machine. In a follow-up post, I'll describe a way to avoid this limitation. It's now up here.

But once it's in operation, this USB pass-through support does work well. I've used it with a range of USB devices, with complete success.

1 comments

@dwragg

I've started twittering recently. If you've always wanted to follow what I was having for breakfast, now you can!

(For your information, it's usually Weetabix. That was the main thing I missed when I was abroad for five years.)

0 comments

Recent kvm versions need kernel 2.6.25 or later

The kvm download page mentions that versions 76 onwards need kernel 2.6.25. What it doesn't mention is what happens if you overlook this requirement. Which is that VMs will hang on the BIOS screen, just after the “Press F12 for boot menu” prompt. You don't get any kind of error message anywhere, so searching the web for help doesn't reveal much. In other words, the kind of issue you could easily bang your head against for a couple of hours.

0 comments