Search Results: "nate"

11 July 2012

Paul Tagliamonte: The "hell-server"

I s pose a better name would be How to preform automated deep-source checks I ve pushed the code to paultag/qlight, and it s just for personal use at the moment. It s built to use paultag/sb around sbuild. Basically, it preforms a crudload of tests such as licensecheck, suspicious-source, pyflakes, bashisms, cppcheck, php in linter mode, and a ton of other checks. You can see a large majority of them in the source file. The batch runner is a singleton , so it s safely called more then once. It s running on a 5-minute cron, and I ve configured a dput target to push it into it s queue & run the enqueue script. Here s some example output from a random package I had lying around:
  ===== build status =====
sbo-run-clang  successful
sbo-run-gcc  successful
  ===== global status =====
Ran plugin extract, exit code 0
Ran plugin watch, exit code 0
Ran plugin licensecheck, exit code 0
Ran plugin validate-source, exit code 0
Ran plugin build, exit code 0
Ran plugin descr, exit code 0
Ran plugin lintian, exit code 0
  ===== descr =====
I: PT: Does this sound right? "gbemol is/are a(n) Graphical frontend for the Music Player Daemon (MPD)"
  ===== piuparts =====
   [last 20 lines]
  ===== licenses =====
BSD (3 clause) 
GPL (v2 or later) 
GPL (v2 or later) GENERATED FILE
GPL (v2 or later) (with incorrect FSF address) 
LGPL (v2 or later) (with incorrect FSF address) 
*No copyright* GPL (v2 or later) 
*No copyright* UNKNOWN
  ===== lintian =====
I: gbemol: spelling-error-in-binary usr/bin/gbemol Wheter Whether
W: gbemol: hardening-no-relro usr/bin/gbemol
I: gbemol: spelling-error-in-manpage usr/share/man/man1/gbemol.1.gz allows to allows one to
  ===== watch =====
-- Scanning for watchfiles in .
-- Found watchfile in ./debian
-- In debian/watch, processing watchfile line:
   http://sf.net/gbemol/gbemol-(.*)\.tar.gz
-- Found the following matching hrefs:
     gbemol-0.3.tar.gz
     gbemol-0.3.1.tar.gz
     gbemol-0.3.2.tar.gz
Newest version on remote site is 0.3.2, local version is 0.3.2
 => Package is up to date
-- Scan finished
  ===== source issues =====
suspicious-source:
bashisms:
script ./ltmain.sh does not appear to have a #! interpreter line;
you may get strange results
possible bashism in ./ltmain.sh line 368 ($RANDOM):
        my_tmpdir="$ my_template -$ RANDOM-0 $$"
error: ./ltmain.sh: Unterminated quoted string found, EOF reached. Wanted: <">
pyflakes:
cppcheck:
[src/gbemol-utils.c:167]: (error) Memory leak: path
[src/libmpdclient.c:1654]: (error) Possible null pointer dereference: output - otherwise it is redundant to check if output is null at line 1663
[src/libmpdclient.c:1655]: (error) Possible null pointer dereference: output - otherwise it is redundant to check if output is null at line 1663
[src/libmpdclient.c:1656]: (error) Possible null pointer dereference: output - otherwise it is redundant to check if output is null at line 1663
[src/libmpdclient.c:1664]: (error) Possible null pointer dereference: output - otherwise it is redundant to check if output is null at line 1663
phplint:
desktop validate:
.//.pc/desktop_file.patch/gbemol.desktop: warning: key "Encoding" in group "Desktop Entry" is deprecated
.//.pc/desktop_file.patch/gbemol.desktop: error: (will be fatal in the future): value "gbemol.png" for key "Icon" in group "Desktop Entry" is an icon name with an extension, but there should be no extension as described in the Icon Theme Specification if the value is not an absolute path
.//.pc/desktop_file.patch/gbemol.desktop: warning: value "Application;AudioVideo;Player;" for key "Categories" in group "Desktop Entry" contains a deprecated value "Application"
mp3check:
mp3val:
fontlint:
ftvalid:
msgfmt:
POFileChecker:
POFileSpell:
pngcheck:
jpeginfo:
ogginfo:
oggz-validate:
xmllint:
lacheck:
jslint:
check for environ calls to home:
check for use of /tmp:
./intltool-extract.in:    $OUTFILE     = "./tmp/$OUTFILE.h"
check for use of system():
./aclocal.m4:    lt_ld_extra= awk '/^include /   system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1;     if (!skip) print \[$]0; skip = 0;  ' < /etc/ld.so.conf   $SED -e 's/#.*//;/^[  ]*hwcap[    ]/d;s/[:,  ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d'   tr '\n' ' ' 
./intltool-merge.in:    return 1 if ((-x $file) or (system("$file -l >$devnull") == 0));
./intltool-merge.in:    system ("$iconv -f $encoding -t UTF-8 <$devnull 2>$devnull");
./intltool-update.in:    return 1 if ((-x $file) or (system("$file --version >$devnull") == 0));
./intltool-update.in:          system ($EXTRACT, "--update", "--srcdir=$SRCDIR",
./intltool-update.in:          system ($EXTRACT, "--update", "--type=$gettext_type", 
./intltool-update.in:    system ("$MSGMERGE", "-o", $outfile, $infile, "$MODULE.pot");
./intltool-update.in:    system ("$MSGFMT", "-o", "$devnull", "--verbose", $output_file);
./intltool-update.in:   system ("$MSGFMT", "-o", "$devnull", "--verbose", "$SRCDIR/$lang.po");
./configure:    lt_ld_extra= awk '/^include /   system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1;     if (!skip) print \$0; skip = 0;  ' < /etc/ld.so.conf   $SED -e 's/#.*//;/^[   ]*hwcap[    ]/d;s/[:,  ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d'   tr '\n' ' ' 
./intltool-extract.in:        system ("mkdir -p $dirname");
./intltool-extract.in:        system("mkdir tmp/"); 
./debian/gbemol.1:the \fBDebian\fP system (but may be used by others).  Permission is 
./debian/manpage.sgml:      the &debian; system (but may be used by others).  Permission is
  ===== sbo-run-clang.log warnings =====
update-binfmts: warning: unable to close /proc/sys/fs/binfmt_misc/register: Invalid argument
update-binfmts: warning: unable to enable binary format python2.6
dpkg-source: warning: extracting unsigned source package (gbemol_0.3.2-2.dsc)
dpkg-buildpackage: warning: using a gain-root-command while being root
gbemol-preferences.c:483:13: warning: 'gbemol_preferences_load_spin' defined but not used [-Wunused-function]
gbemol-net.c:60:11: warning: variable 'res' set but not used [-Wunused-but-set-variable]
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libfontconfig.so.1 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libatk-1.0.so.0 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against librt.so.1 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libgio-2.0.so.0 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libcairo.so.2 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libpango-1.0.so.0 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libpangocairo-1.0.so.0 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libfreetype.so.6 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libpangoft2-1.0.so.0 (it uses none of the library's symbols).
dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe
     + add misc-depends to fix lintian warning.
  ===== sbo-run-gcc.log warnings =====
dpkg-source: warning: extracting unsigned source package (gbemol_0.3.2-2.dsc)
dpkg-buildpackage: warning: using a gain-root-command while being root
gbemol-preferences.c:483:13: warning: 'gbemol_preferences_load_spin' defined but not used [-Wunused-function]
gbemol-net.c:60:11: warning: variable 'res' set but not used [-Wunused-but-set-variable]
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libfontconfig.so.1 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libatk-1.0.so.0 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against librt.so.1 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libgio-2.0.so.0 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libcairo.so.2 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libpango-1.0.so.0 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libpangocairo-1.0.so.0 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libfreetype.so.6 (it uses none of the library's symbols).
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/gbemol/usr/bin/gbemol was not linked against libpangoft2-1.0.so.0 (it uses none of the library's symbols).
dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe
     + add misc-depends to fix lintian warning.
Not as interesting as it can get, but still pretty cool. Andrea, I swear I m not picking on you :) More to come later (hopefully) :)

9 July 2012

Julien Danjou: Logitech K750 keyboard and Unifying Receiver Linux support

A year ago, I bought a Logitech Wireless Solar Keyboard K750. I'm particularly picky on keyboards, but this one is good. It has an incredible useful feature: while being wireless, it has no need for disposable or rechargeable batteries, it uses solar power! Logitech Wireless Solar Keyboard K750 My problem is that there's obviously no way to know the battery status from Linux, the provided application only working on Windows. And one dark night, while fragging on QuakeLive, my keyboard stopped working: it had no battery left. This activity being quite energy consuming, it emptied the whole battery. Someone should write code to get the battery status and light meter from Linux: challenge accepted! How the keyboard works Logitech Unifying Receiver This keyboard, like many of the new wireless devices from Logitech, uses the Unifying interface. It's an USB receiver that can be attached up to 6 differents devices (mouse, keyboards ). On old Linux kernel, the Unifying receiver is recognized as only one keyboard and/or one mouse device. Recently, a driver called hid-logitech-dj has been added to the Linux kernel. With this driver, each device attached to the receiver is recognized as one different device. What the Logitech application does Logitech Solar App The Logitech application under Windows works that way: you launch it, and it displays the battery charge level. On the keyboard, there's a special "light" button (up right). When pressed, a LED will light up on the keyboard: green if the keyboard is receiving enough light and is charging, red if the keyboard does not receive enough light and is therefore discharging. Pushing this same button while the application is running will makes the light meter activated: the application will tell you how much lux your keyboard is receiving. Let's reverse engineer this As far as I know, there's nothing in the USB HID protocol that handles this kind of functionality (battery status, light meter ) in a standard way. So the first task to accomplish is, unfortunately, to reverse engineer the program. I discovered a bit too late that Drew Fisher did a good presentation on USB reverse engineering at 28c3. You might want to take a look at it if you want to reverse engineer on USB. I did not need it, but I learned a few things. Anyway, my plan was the following: run the Logitech application inside a virtual machine running Windows, give it direct access to the USB keyboard, and sniff what happens on the USB wire. To achieve that, you need a virtual machine emulator that can do USB pass-through. Both KVM and VirtualBox can do that, but VirtualBox works much better with USB and allow hot(un)plugging of devices, so I used it. To sniff what happens on the USB, you need to load the usbmon Linux kernel module. Simply doing modprobe usbmon will work. You can then use Wireshark which know how to use usbmon devices and understand the USB protocol. USB stuff you need to know You don't need to know much about USB to understand what I'll write about below, but for the sake of comprehensibility I'll write a couple of things here before jumping in. To communicate with an USB device, we communicate with one of its endpoints. Endpoints are regrouped into an interface. Interfaces are regrouped into a configuration. A device might contains one or several configurations. There's also several types of packets in the USB wire protocol, and at least two of them interest us there, they are: All of this and more is well (and better) explained in the chapter 13 of Linux Device Drivers, Third Edition. Sniffed data Once everything was set-up, I ran my beloved Wireshark. There's a an URB of type interrupt sent each time you press any key with some data in it. Therefore I advise you to plug another keyboard (or use the laptop keyboard if you're doing this on a laptop), otherwise you'll get crazy trying to sniff the keyboard you're typing on. At this point, just launching the application does a bunch of USB traffic. Pressing the "light" button on the keyboard makes even more USB packets coming in and out. Here's the interesting packets that I noticed once I excluded the noise: With all this, the next step was clear: understand the packets and reproduce that exchange under Linux. What the packets mean The "go for the light meter" packet The packet sent from the computer to the keyboard is the following. <figure>
Frame 17: 71 bytes on wire (568 bits), 71 bytes captured (568 bits)
    Frame Length: 71 bytes (568 bits)
    Capture Length: 71 bytes (568 bits)
USB URB
    URB id: 0xffff880161997240
    URB type: URB_SUBMIT ('S')
    URB transfer type: URB_CONTROL (0x02)
    Endpoint: 0x00, Direction: OUT
        0... .... = Direction: OUT (0)
        .000 0000 = Endpoint value: 0
    Device: 6
    URB bus id: 1
    Device setup request: relevant (0)
    Data: present (0)
    URB sec: 1340124450
    URB usec: 495643
    URB status: Operation now in progress (-EINPROGRESS) (-115)
    URB length [bytes]: 7
    Data length [bytes]: 7
    [Response in: 18]
    [bInterfaceClass: HID (0x03)]
    URB setup
        bmRequestType: 0x21
            0... .... = Direction: Host-to-device
            .01. .... = Type: Class (0x01)
            ...0 0001 = Recipient: Interface (0x01)
    bRequest: SET_REPORT (0x09)
    wValue: 0x0210
        ReportID: 16
        ReportType: Output (2)
    wIndex: 2
    wLength: 7
0000  40 72 99 61 01 88 ff ff 53 02 00 06 01 00 00 00   @r.a....S.......
0010  22 ad e0 4f 00 00 00 00 1b 90 07 00 8d ff ff ff   "..O............
0020  07 00 00 00 07 00 00 00 21 09 10 02 02 00 07 00   ........!.......
0030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0040  10 01 09 03 78 01 00                              ....x..
</figure> What's here interesting is the last part representing the data. wLength says that the length of the data is 7 bytes, so let's take a look at those 7 bytes: 10 01 09 03 78 01 00. Well, actually, you can't decode them like that, unless you're a freak or a Logitech engineer. And I have actually no idea what they mean. But sending this to the keyboard will trigger an interesting thing: the keyboard will start sending URB interrupt with some data without you pressing any more key. The "light meter and battery values" packet This is most interesting packet. This is the one sent by the keyboard to the host and that contains the data we want to retrieve. <figure>
Frame 1467: 84 bytes on wire (672 bits), 84 bytes captured (672 bits)
    Frame Length: 84 bytes (672 bits)
    Capture Length: 84 bytes (672 bits)
USB URB
    URB id: 0xffff88010c43c380
    URB type: URB_COMPLETE ('C')
    URB transfer type: URB_INTERRUPT (0x01)
    Endpoint: 0x83, Direction: IN
        1... .... = Direction: IN (1)
        .000 0011 = Endpoint value: 3
    Device: 2
    URB bus id: 6
    Device setup request: not relevant ('-')
    Data: present (0)
    URB sec: 1334953309
    URB usec: 728740
    URB status: Success (0)
    URB length [bytes]: 20
    Data length [bytes]: 20
    [Request in: 1466]
    [Time from request: 0.992374000 seconds]
    [bInterfaceClass: Unknown (0xffff)]
Leftover Capture Data: 1102091039000c061d474f4f4400000000000000
0000  80 c3 43 0c 01 88 ff ff 43 01 83 02 06 00 2d 00   ..C.....C.....-.
0010  5d c5 91 4f 00 00 00 00 a4 1e 0b 00 00 00 00 00   ]..O............
0020  14 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00   ................
0030  02 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00   ................
0040  11 02 09 10 39 00 0c 06 1d 47 4f 4f 44 00 00 00   ....9....GOOD...
0050  00 00 00 00                                       ....
</figure> This packets come in regularly (1 per second) on the wire for some time once you sent the "go for the light meter" packet. At one point they are emitted less often and do not contain the value for the light meter anymore, suggesting that the control packet sent earlier triggers the activation of the light meter for a defined period. Now you probably wonder where the data are in this. They're in the 20 bytes leftover in the capture data part, indicated by Wireshark, at the end of the packet: 11 02 09 10 39 00 0c 06 1d 47 4f 4f 44 00 00 00 00 00 00 00. Fortunately, it was easy to decode. Knowing we're looking for 2 values (battery charge and light meter), we just need to observe and compare the packet emitted on the wire with the values displayed by the Logitech Solar App. To achieve this, I looked both at the Logitech Solar App and Wireshark while bringing more and more light near the keyboard, increasing the lux value received by the meter on the Solar App, and saw that the fields represented in blue (see below) where changing in Wireshark. Since 2 bytes were changing, I guessed that it was coded on 16 bits, and therefore it was easy to correlate the value with the Solar App. <figure>
[ ....9....GOOD....... ]
11 02 09 10 39 00 0c 06 1d 47 4f 4f 44 00 00 00 00 00 00 00
4 bytes - 1 byte for battery charge - 2 bytes for light meter - 2 bytes - 4 bytes for GOOD - 7 bytes
</figure> In this example, the battery has a charge of 0x39 = 57 % and the light meter receives 0x0c = 12 lux of light. It's basically dark, and that makes sense: it was night and the light was off in my office, the only light being the one coming from my screen. I've no idea what the GOOD part of the packet is about, but it's present in every packet and it's actually very handy to recognize such a packet. Therefore I'm considering this as some sort of useful mark for now. For the other bytes, they were always the same (0x11 0x2 0x9 0x10 at the beginning, 7 times 0x00 at the end). The 2 bytes between the light meter and GOOD probably mean something, but I've no idea what for now. Building our solar app Now we've enough information to build our own very basic solar application. We know how to triggers the light meter, and we know how to decode the packets. We're going to write a small application using libusb. Here's a quick example. It's not perfect and does not check for error codes, be careful. <figure>
/* Written by Julien Danjou <julien> in 2012 */
#include <linux/hid.h>
#include <libusb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
 
    libusb_context *ctx;
    libusb_init(&ctx);
    libusb_set_debug(ctx, 3);
    /* Look at the keyboard based on vendor and device id */
    libusb_device_handle *device_handle = libusb_open_device_with_vid_pid(ctx, 0x046d, 0xc52b);
    fprintf(stderr, "Found keyboard 0x%p\n", device_handle);
    libusb_device *device = libusb_get_device(device_handle);
    struct libusb_device_descriptor desc;
    libusb_get_device_descriptor(device, &desc);
    for(uint8_t config_index = 0; config_index < desc.bNumConfigurations; config_index++)
     
        struct libusb_config_descriptor *config;
        libusb_get_config_descriptor(device, config_index, &config);
        /* We know we want interface 2 */
        int iface_index = 2;
        const struct libusb_interface *iface = &config->interface[iface_index];
        for (int altsetting_index = 0; altsetting_index < iface->num_altsetting; altsetting_index++)
         
            const struct libusb_interface_descriptor *iface_desc = &iface->altsetting[al>tsetting_index];
            if (iface_desc->bInterfaceClass == LIBUSB_CLASS_HID)
             
                libusb_detach_kernel_driver(device_handle, iface_index);
                libusb_claim_interface(device_handle, iface_index);
                unsigned char ret[65535];
                unsigned char payload[] = "\x10\x02\x09\x03\x78\x01\x00";
                if(libusb_control_transfer(device_handle,
                                           LIBUSB_REQUEST_TYPE_CLASS   LIBUSB_RECIPIENT_INTERFACE,
                                           HID_REQ_SET_REPORT,
                                           0x0210, iface_index, payload, sizeof(payload) - 1, 10000))
                 
                    int actual_length = 0;
                    while(actual_length != 20   strncmp((const char *) &ret[9], "GOOD", 4))
                        libusb_interrupt_transfer(device_handle,
                                                  iface_desc->endpoint[0].bEndpointAddress,
                                                  ret, sizeof(ret), &actual_length, 100000);
                    uint16_t lux = ret[5] << 8   ret[6];
                    fprintf(stderr, "Charge: %d %%\nLight: %d lux\n", ret[4], lux);
                 
                libusb_release_interface(device_handle, iface_index);
                libusb_attach_kernel_driver(device_handle, iface_index);
             
         
     
    libusb_close(device_handle);
    libusb_exit(ctx);
 
</figure> What the program is doing is the following: This gives the following:
Found keyboard 0x0x24ec8e0
Charge: 64 %
Light: 21 lux
Challenge accomplished! To be continued Unfortunately, this approach has at least one major drawback. We have to disconnect the Logitech Unifying Receiver from the kernel. That means that while we're waiting for the packet, we're dropping packets corresponding to other events from every connected device (key presses, pointer motions ). In order to solve that, I sent a request for help on the linux-input mailing list. That way, I learned that Logitech is actually using the HID++ protocol to communicate with the devices using the Unifying Receiver. Lars-Dominik Braun managed to get the HID++ specifications from Logitech and published them with their authorization. This opens a whole new world. With that document, I may be able to understand the part I reverse engineered and convert this to a more useful and generic library using the hidraw interface (so we don't have to disconnect the devices from the kernel driver).

Benjamin Mako Hill: The Global Iron Blogger Network

Since last November, I've been participating in and coordinating Iron Blogger: a drinking club where you pay $5 to a "beer" pool if you fail to blog weekly. The revival of Iron Blogger in Boston has been a big success. Even more exciting, however, is that Iron Blogger concept has spread. There are now two other Iron Blogger instances: in San Francisco coordinated by Parker Higgens, and in Berlin run by Nicole Ebber and Michelle Thorne. Yesterday, we convened a virtual meeting of the Global Iron Blogger Council (i.e., an email thread) and we all agreed a new on iron blogger rule that might sweeten the deal for jet-setting prospective Iron Bloggers: any paid-up member of any Iron Blogger club can attend meet-ups in any other Iron Blogger cities if they happen to be in town for one. Because We Are One. If you want to join us in Boston, we have some room through attrition. Rust bloggers, perhaps? If you'd like to join, you should contact me. And if you'd like to set up your own in a different city, the code is in git. One warning, however. As those of us that have set it up have figured out, the documentation for the software to run Iron Blogger is between poor and non-existent. If you do want to set up your own instance, please get in touch. I'm happy to give you some pointers that you'll probably need but, more importantly, I'd like to work with the next brave soul to put together documentation of the setup process along the way.

Russell Coker: Breaking SATA Connectors

I ve just broken my second SATA connector. This isn t a lot considering the number of hard drives I ve worked with, but it s still really annoying as I generally don t break things. The problem is that unplugging a SATA cable requires pushing a little clip, this isn t overly difficult but it unfortunately doesn t fit well with habits formed from previous hardware. The power cables used for hard drives based on the ST-506 interface which was copied for the IDE interface was large and had a fairly tight fit. Removing such a cable requires a significant amount of force which is about the same as the amount of force required to break a SATA connector. When I first started using PCs a reasonably configured AT system cost over $5,000 (maybe something like $10,000 in today s money). With that sort of price hardly anyone had a set of test PCs. When hardware prices dropped such that hard drives of reasonable size became reasonably affordable on the second-hand market I bought more disks and used some for extra storage and some for testing software. As there was nothing like VMWare for testing OS images the way to test a new OS was to plug in a different hard drive and boot it. So I got a lot of practice at removing IDE power cables with as much force as was necessary. Now I own a pile of test PCs, SATA disks less than 100G are free, I use Xen for a lot of my testing, and generally I have much less need to swap hard drives around. In most situations in which I would swap hard drives in the 90 s I will now swap PCs and I have piles of PCs ready for this purpose. So I haven t had enough practice with SATA disks to develop habits for safely removing them. So far this lack of habit development has resulted in damaging two disks due to changing drives while not concentrating enough. Fortunately duct-tape works well for holding a SATA connector in place when the plastic that attaches to the clip is broken. Related posts:
  1. Strange SATA Disk Performance Below is a GNUPlot graph of ZCAV output from a...
  2. Vibration and Strange SATA Performance Almost two years ago I blogged about a strange performance...
  3. Dell PowerEdge T105 Today I received a Dell PowerEDGE T105 for use by...

7 July 2012

Keith Packard: FEC

Forward Error Correction with the TI CC1120 Sub-GHz transceiver We re building a new, fancier flight computer and decided to give the new, fancier TI CC1120 chip a try. It has significantly more transmit power (+16dBm) and receive sensitivity (-109dBm) than the transciever built in to the TI CC1111 RF SoC that we ve built our other boards with. Given that we d already decided to use a fancier STM32L processor, using the nicest stand-alone radio chip we could find seemed to make good sense. One of the nice features found in the CC1111 is support for FEC using a 1/2 rate constraint length 4 convolutional code. Both the encoder and the soft-decision Viterbi decoder are built right into the chip; all we had to do was flip a couple of bits and we got error correction, interleaving, data whitening and CRC checking all for free. We assumed that, as the CC1120 was advertised as a better replacement for our CC1111 radio, that it would also include all of these fine features. After we got the chip all soldered down to our first prototype boards, we read through the reference manual looking for the right register values to flip for forward error correction. We found support for CRC computation and data whitening, but no mention of interleaving or forward error correction at all. Thanks, TI. Of course, without the FEC pieces, the other packet handling hardware is worthless you can t exactly do a CRC on the encoded data and expect it to be useful on the other end of the link, and data whitening happens after the CRC. Basic CC1120 driver I assumed I d eventually figure out something to do about the FEC pieces and started writing a basic CC1120 driver AltOS, the operating system used in all of our projects. I started with the transmit side, as that seemed easier as I could use the existing packet hardware by uploading the desired bit sequence using whatever fancy encoding desired and the hardware would happily transmit it. I first tested that using low data-rate bits (2kbps), transmitting an alternating sequence of zeros and ones to generate a 1kHz tone on a regular 70cm receiver. That seemed to work just fine, demonstrating that I had some grasp of the basic operation of the chip. Convolutional Encoding in Software Not to be daunted by a small challenge in software, I set out to replicate the encoding scheme used in the CC1111 chips for use in our CC1120-based design. We obviously want our CC1120 boards to interoperate with the CC1111 boards. Fortunately, TI fully documents the CRC, data whitening, convolutional encoding and interleaving done in the hardware. I created my own implementation of the encoder (licensed, as usual, under the GPLv2) which you can see in the file ao_fec_tx.c It s not quite as flexible as the hardware, it always whitens the data and always appends the CRC bytes to the end of the packet, along with the necessary trellis termination bytes. The core of that code is surprisingly simple:
static const uint8_t ao_fec_encode_table[16] =  
/* next 0  1      state */
    0, 3,   /* 000 */
    1, 2,   /* 001 */
    3, 0,   /* 010 */
    2, 1,   /* 011 */
    3, 0,   /* 100 */
    2, 1,   /* 101 */
    0, 3,   /* 110 */
    1, 2    /* 111 */
 ;
uint8_t
ao_fec_encode(const uint8_t *in, uint8_t len, uint8_t *out)
 
    uint8_t     extra[AO_FEC_PREPARE_EXTRA];
    uint8_t     extra_len;
    uint32_t    encode, interleave;
    uint8_t     pair, byte, bit;
    uint16_t    fec = 0;
    const uint8_t   *whiten = ao_fec_whiten_table;
    extra_len = ao_fec_prepare(in, len, extra);
    for (pair = 0; pair < len + extra_len; pair += 2)  
        encode = 0;
        for (byte = 0; byte < 2; byte++)  
            if (pair + byte == len)
                in = extra;
            fec  = *in++ ^ *whiten++;
            for (bit = 0; bit < 8; bit++)  
                encode = encode << 2   ao_fec_encode_table[fec >> 7];
                fec = (fec << 1) & 0x7ff;
             
         
        interleave = 0;
        for (bit = 0; bit < 4 * 4; bit++)  
            uint8_t byte_shift = (bit & 0x3) << 3;
            uint8_t bit_shift = (bit & 0xc) >> 1;
            interleave = (interleave << 2)   ((encode >> (byte_shift + bit_shift)) & 0x3);
         
        *out++ = interleave >> 24;
        *out++ = interleave >> 16;
        *out++ = interleave >> 8;
        *out++ = interleave >> 0;
     
    return (len + extra_len) * 2;
 
ao_fec_encode_table takes care of the convolutional piece, ao_fec_whiten_table (not shown) contains the data whitening codes while the little loop at the bottom does the interleaving. I didn t spend a lot of time optimizing this as it seemed to run plenty fast on the 32MHz processor. With the bits all nicely encoded, I passed them to my simple CC1120 driver and let it send them along to our CC1111 receiver. Much to my delight, with only a few bugs fixed, it worked just fine! I d managed to get one direction working, validating the hardware and making it clear that we d at least be able to use the board in flight for telemetry. Getting Soft-decision data out of the CC1120 In packet mode, the CC1120 receiver converts the incoming GFSK stream directly into bits, making its best guess as to whether the detected value was a one or zero. Of course, like any FM modulation, the receiver will be producing intermediate values, especially when the signal is weak or masked by interference. A Viterbi decoder can make good use of this information;these noisy intermediate values are less influential in the final resulting path cost which allows the strong 0/1 values to pull the solution to the right one. Soft decision decoding yields a theoretical 2dB gain over hard decision decoders, and given our desire for maximum packet reception over long distances, it seemed important to make this work. The CC1120 has a way to recover the soft decision values, but only one 8-bit value at a time. It does, however, helpfully provide a GPIO wire which can be programmed to interrupt the CPU when the soft decision data has arrived. So, I hooked up a GPIO line on the processor to the GPIO line on the CC1120 and let it interrupt once per bit time, or 38400 times per second, to read this valuable soft decision data out of the radio part. According to TI support, this is the only way to make this work, and that they generally recommend that developers use the packet mode stuff and throw away this valueable source of data. I was happily surprised to learn that the STM32L can in fact survive this interrupt rate, and by setting interrupt priorities appropriately, I manage to reliably capture an entire packets worth of data without dropping a single bit. I set up a simple packet dumping function to run on the prototype board and captured raw encoded bytes from our CC1111-based flight computer so that I d have some real data to work from. Soft-decision Viterbi Decoding The sample encoding implementation from TI made that piece fairly straightforward. Lacking a similar sample for the decoding piece meant that I d be starting from scratch. And, implementing something that seemed like magic to me when I started. I started by reading a few articles on Viterbi decoding: I found Chip Fleming s tutorial very useful as it included a bunch of worked examples using a convolutional encoders with constraint length (k) of 3 instead of 4; this makes all of the trellis diagrams half the size. I also sent my friend, Phil Karn, a query about this process, and he responded with a bunch of helpful suggestions, while also recommending that I just steal his DSP and FEC library implementation. Of course, I don t like using code that I can t understand, and his code only implements much longer codes than I needed, so I d have to understand it anyways to make it work for me. Phil s code is a marvel, but it s not exactly comprehensible to someone who doesn t even know what a Viterbi decoder is supposed to do. So, with Chip s tutorial on my screen, I wrote a primitive Viterbi decoder. This did only the Viterbi step, and split that into two phases. The first computed the cost for each state in the system for every received pair of symbols received. It also tracked the chain of states through the entire decode process:
    for (state = 0; state < 8; state++)  
        struct ao_soft_sym zero = ao_soft_sym(ao_fec_encode_table[state * 2 + 0]);
        struct ao_soft_sym one = ao_soft_sym(ao_fec_encode_table[state * 2 + 1]);
        uint8_t zero_state = ao_next_state(state, 0);
        uint8_t one_state = ao_next_state(state, 1);
        int zero_cost = ao_cost(s, zero);
        int one_cost = ao_cost(s, one);
        zero_cost += cost[b][state];
        one_cost += cost[b][state];
        if (zero_cost < cost[b+1][zero_state])  
            prev[b+1][zero_state] = state;
            cost[b+1][zero_state] = zero_cost;
         
        if (one_cost < cost[b+1][one_state])  
            prev[b+1][one_state] = state;
            cost[b+1][one_state] = one_cost;
         
     
At the end of the packet, it found the least costly path and walked that from back to front, generating output bits (yes, one bit per element of the bits array):
for (state = 1; state < 8; state++)  
    if (cost[b][state] < c)  
        c = cost[b][state];
        min_state = state;
     
 
for (b = len/2; b > 0; b--)  
    bits[b-1] = min_state & 1;
    min_state = prev[b][min_state];
 
Completely separate from this code were the interleaving and data whitening stages. Keeping those separate allowed them to be tested independently, which made debugging them far easier. None of this code ever ran on the STM32L processor, it was instead run in a test framework on my laptop. I first got this working with data generated by the software convolutional encoder, then I managed to get it to decode the raw packets that I had recorded directly from the receiver it self. This marked a significant milestone in my mind I d managed to replace, in software, the CC1111 FEC encoder and decoder. However, the decoder performance was not fast enough to manage back-to-back packets yet. Having something in hand that worked meant that further development would be directly comparable to something that did work, making optimization much easier. Yet another lesson in making it work, and then making it work fast. Optimizing the Viterbi Decoder The first step was to reduce memory usage within the decoder. While it s best to defer computing the path until the very last bit has been received, it s also true that the chances of a bit affecting old data reduces as the distance between the new and old data increases. With the rule of thumb being a distance of k 6 or k 7, I saved 32 output bits for each state and wrote the oldest of 8 each time the buffer filled up, making a distance of 24 bits between the newest saved data and the current decoding position. That meant a fixed amount of storage was needed for an arbitrarily long packet. I tested a variety of different history sizes from 8 to 56 bits (cooresponding to 16, 32 and 64 bits of saved data for each state). With 100000 random packets generated that had gaussian noise added to each bit, here are the error rates for the different history lengths:
History LengthTotal PacketsCorrectIncorrect
8 bits10000090520 (90.52%)9480 (9.48%)
24 bits10000093614 (93.61%)6386 (6.39%)
56 bits10000093620 (93.62%)6380 (6.38%)
The performance of the 8-bit history and 16-bit history versions turned out to be essentially identical (given the 32-bit nature of the STM32L, that shouldn t be too surprising). The performance of the 56-bit version, which manipulated uint64_t data types was sigificantly slower, and given the very modest benefit, deemed not worth it. If we move to a larger constraint length (k > 4), or started using a punctured convolutional encoding, we would want to re-measure this. The next step was to combine the de-interleaving, decoding, de-whitening and CRC computation into a single loop. This would eliminate a pile of data copying and extra memory usage. Nothing fancy here, but it made enough of a difference that I could decode most of the incoming packets now, dropping only about 25% of them. To get to being able to decode every packet, I needed to start decoding the packet while it was being received. Because of interleaving, I had to have 32 bits of data to be able to decode anything, so it was a simple matter of having my per-soft-value interrupt handler start the decoder going after each interleave block of data was received. With this in place, I was able to decode a 76-byte payload (160 transmitted bits) in 14.7 ms, or just about 50% of the time it took to transmit the packet. Unrolling one of the inner decoding loops eliminated a bunch of computation and sped this up even more, decoding packets in 9.5ms. Success at last, a solid 100% of packets received were being decoded, as long as the CPU was otherwise idle. Finally, I went and re-read Phil Karn s code and pondered over how it works. It was opaque until I wrote a message back to Phil asking how it worked and pointing out sections that were confusing. Fortunately, simply phrasing my confusion in words made me understand how the code works. Here s my original code for computing the per-state cost metric:
/* Metric for a zero bit */
uint32_t    bitcost = ((uint32_t) (s0 ^ ao_fec_decode_table[(state<<1)]) +
               (uint32_t) (s1 ^ ao_fec_decode_table[(state<<1)+1]));
 
    /* Total path metric and state for a zero bit */
    uint32_t    cost0 = cost[p][state] + bitcost;
    uint8_t     state0 = ao_next_state(state, 0);
    /* Compare the total path metric against all existing
     * metrics heading into the same new state, choosing
     * the least expensive and killing the others.  Record
     * the new lowest cost and output bit.
     */
    if (cost0 < cost[n][state0])  
        cost[n][state0] = cost0;
        bits[n][state0] = (bits[p][state] << 1)   (state & 1);
     
 
 
    /* Total path metric and state for a one bit.  Because
     * encoding a one is always exactly the opposite of
     * encoding a zero from any state, this cost is
     * 255*2 - bitcost
     */
    uint32_t    cost1 = cost[p][state] + 510 - bitcost;
    uint8_t     state1 = ao_next_state(state, 1);
    if (cost1 < cost[n][state1])  
        cost[n][state1] = cost1;
        bits[n][state1] = (bits[p][state] << 1)   (state & 1);
     
 
Before this loop is run, I have to initialize cost[n] to a large value so that the comparisons will be true for the first case to reach each state. Phil s code, in contrast, doesn t have to initialize cost[n] as we know which two states can reach any possible new state. His code looks like this:
/* Metric for a zero bit */
bitcost = ((uint32_t) (s0 ^ ao_fec_decode_table[(state<<1)]) +
       (uint32_t) (s1 ^ ao_fec_decode_table[(state<<1) 1]));
/* Only state and state+4 reach state<<1 with a zero bit */
/* Cost from state to state<<1 for a zero bit*/
m0 = cost[p][state] + bitcost;
/* Cost from state+4 to state<<1 for a zero bit */
m1 = cost[p][state+4] + (510 - bitcost);
/* Which source state is cheaper? */
bit = m0 > m1;
/* Record the cheaper cost and the add to the path of bits */
cost[n][state<<1] = bit ? m1 : m0;
bits[n][state<<1] = (bits[p][state + (bit<<2)] << 1)   (state&1);
/* State and state+4 reach (state<<1)+1 with a one bit */
/* Cost from state to (state<<1)+1 for a one bit */
m0 -= (bitcost+bitcost-510);
/* Cost from state+4 to (state<<1)+1 for a one bit */
m1 += (bitcost+bitcost-510);
/* Which source state is cheaper? */
bit = m0 > m1;
/* Record cheaper cost and add to the path of bits */
cost[n][(state<<1)+1] = bit ? m1 : m0;
bits[n][(state<<1)+1] = (bits[p][state + (bit<<2)] << 1)   (state&1);
This code does two states at a time, and so while it s slightly longer than the above, it only needs to run half as many times. The resulting code now decodes packets in 5.7ms. The final version of the code can be see in ao_fec_rx.c The whole AltOS operating system, with many drivers and support for CC1111, AVR and STM32L processirs is available, under the GPLv2 from git://git.gag.com/scm/git/fw/altos

6 July 2012

Christian Perrier: DebConf running: take 4 (Masaya volcano)

Yet another Grand Plan today: run in Masaya Volcan National Park. Masaya Volcano is one of the most active volcanoes in Nicaragua. It is located only 20km south-east of Managua, so going there is as easy as renting a taxi. The original plan was to drive to the entrance of the National park (on the road to Masaya city), then run up to the volcan, so from 250m altitude up to about 600m. I therefore rented a taxi with the kind help of Norman, and we agreed to meet up at 08:30 at the hotel, along with No l and Daniel (who was planning to walk up, not running). After discussing here or there, Kurt and Gaudenz joined, both with the intent of running up. Others would also have liked to join, but I wasn't in the mood of organizing a full bus of Debconfers..:-). My plan was to enjoy pyself the hike...not to manage several taxis, etc. We thus packed in Denis blue taxi...a fancy and very visible customized blue car that looked like it had been the topic of on episode of the "Pimp My Ride" TV show..:-) Sitting 4 people at the back of a regular car without hitting some blue neon lights, or 7" TV screens is kinda tricky, but we made it. When arriving at the park's entrance, we however learned that it is forbidden to walk or hike up the road by foot, because of potential high concentrations of Carbon Dioxide. Sadly, we then had to pack again in the car and go up with it. After reaching the parking close to the volcano's active crater (that is said to have a small lava lake at its bottom, one of the very few in the world), we decided to head up for going round the Nindira crater, an inactive crater located slightly above. Unfortunately, again, the path around the Masaya crater is forbidden to walk on, because of landslides. We indeed still had great fun by running around this crater (which is about a 2.5 kilometers round trip, very very hilly and sometimes hard to run on such as a mountain path. After about 50 minutes and two laps (after all, we had a giant stadium!), we headed back to the parking, packed 5 sweating geeks in the car and went back to the hotel. Full GPS trace is here. I also put a few pictures on Facebook, supposedly visible by anybody : Masaya crater and Nindiri crater.

Matthew Garrett: DMI checks are a last resort

Most x86 devices export various bits of system information via SMBIOS, including the system manufacturer, model and firmware version. This makes it possible for the kernel to alter its behaviour depending on the machine it's running on, usually referred to as "DMI quirking". This is a very attractive approach to handling machine-specific bugs - unfortunately it also means that we often end up working around symptoms with no understanding of the underlying issue.

Almost all x86 hardware is tested with Windows. For the most part vendors don't ship devices that don't work - if you install a stock copy of Windows on a system, you expect it to boot successfully and reboot properly. Basic ACPI functionality should be present and correct, including processor power-saving states. Time should pass at something approximating the real rate. And since stock Windows isn't updated with large numbers of DMI quirk entries, the hardware needs to do this with an operating system that's already shipped.

Which means that if Linux doesn't provide the same level of functionality, it means we're doing something different to Windows. Sometimes this is because we're doing something fundamentally different with the hardware - the HP NX6125, for example, resets its thermal trip points if the timer is set up in a different way to Windows. In this case we've decided that the additional functionality of doing things the Linux way is worth it, and we'll just blacklist the small set of machines that are broken by it.

But other times there's no need for the difference. For years we were triggering system reboots in a different way to Windows and then adding DMI workarounds for any systems that didn't work. The problem with this approach is that it's basically impossible to guarantee that you've found the full set of broken hardware. It's very easy to add another DMI quirk, but it doesn't solve the problem for anyone who bought a machine, tried Linux and gave up when they found reboot didn't work. More recently we've added a pile of quirks for Dells - turns out that in all cases we're working around a bug in their firmware that hangs if we're using VT-d.

We typically don't merge code that fixes a specific example of a problem without at least considering whether there's a wider class of similar problems that could all be solved at once. We should take the same attitude to DMI quirks. Sometimes they're the least harmful way of handling an issue, but most of the time they're just fixing one person's itch and leaving a larger number of people to continue cursing at Linux. There should at least be a demonstration of an attempt to understand the underlying problem before just adding another quirk, and every patch that permits the removal of some DMI checks should be greeted with great cheer.

comment count unavailable comments

5 July 2012

Don Armstrong: Wikipedia Deletion Reviews

Many community driven projects have a problem with overgrown bureaucratic processes reducing the desire and ability of casual contributors to contribute. Debian has struggled with this problem, with efforts like Debian Maintainers and sponsorship to address it, but it's insidious and difficult to completely overcome. I recently ran into this problem again with Wikipedia, where I'm a casual contributor (I probably average an edit a month). Sometime in 2006, I uploaded an image of a Boojum tree I took in 2004 to Wikipedia to provide an image for the Boojum tree article. It wasn't a particularly awe inspiring image, as I took it while I was teaching second quarter freshmen biology on campus, and showing the students the awesome Botanical Gardens at UCR. In 2011, a Wikipedia user asked for deletion of the image because of some confusion about the copyright on the image, as Apache::Gallery's default template footer contains Apache::Gallery's copyright. I didn't notice that during the 7 day deletion review period because I rarely log into Wikipedia. A few days ago, I noticed the deletion and asked for a Deletion Review. I assumed that my explanation that the copyright notice was for Apache::Gallery would be understood (or at least believed), and that at least the original reason for the deletion would be seen to be invalid. Instead, during the process I was questioned as to whether I actually took the picture, why I used GPLv2+ for the pictures, whether I was claiming other people's images, and whether the image was actually good enough to be in Wikipedia in the first place. Hundreds of lines of text, an edit to the template in A::G, hours wasted, people still unsatisfied, and the potential contributor (myself) feeling so annoyed with the entire process that I bothered to write this blog entry. While I'm not sure what to do about Wikipedia, I've been forcibly reminded of how important enabling easy contributions are, and how alienated one can feel when one is stymied by them to the point that your (admittedly insignificant) contribution to a project no longer seems worth the effort.

Christian Perrier: DebConf running: take 3

The Grand Plan today was reaching the end of the road I already explored on Tuesday. Named "Camino Las Viudas", it's climbing in the southern hills up to a place named "Intermzeeo del Bosque", apparently a very fancy (and expensive) restaurant. The road climbs in the apparently "rich" neighbourhood of Managua, with very fancy villas as guarded by private security, as well as private condominiums, guarded as well. What's funny to see is that, at the bottom of the road, when it crosses a large avenue (Pista Suburbana Espana), you can find several auto-rickshaws, just like those you find everywhere in India. Those autos apparently drive people who happen to work in these villas (like maids, gardeners, security guards, etc.) up to the place they work. We even met two cows wandering on the road and I hesitated waiting for a rickshaw to show up and take a pic of the road (with holes), the auto and the cows, then pretending that I'm no longer in Nicaragua but back in Karnataka. I did the run along with No l K the, who I was very happy to find again, restoring our now famous Debconf Runners Duet. We even found the German Embassy! Though climb, even if we took care to start at 6 a.m. to avoid the heat (and also the traffic and noise). No l unfortunately had to give up at 1km from the top of the road, when a 15% climb suddenly "killed" his legs. I need to train him more for ups and downs..:-) I could continue the road and finally reached the restaurant....which was guarded by private security (as apparently everything in this country) who unfortunately didn't let me in despite my desperate attempts to convince him, in broken Spanish, that I just wanted to take a few pictures and not place a bomb or rob someone... So, I gota little bit disappointed and the only option was then....to run down for another 8.5 kilometers, accelerating all the way, to finish nearly at 14 km/h on Managua's sidewalks...Fun. Great run (nearly 400m positive slope in less than 17km). Next challenge : find another such nice run in the neighbourhood! Maybe Volcan Masaya tomorrow. GPS trace is here.

4 July 2012

Michael Banck: 4 Jul 2012

Update on computational chemistry packages in Debian

For many years, me and the Debichem team maintained two computational chemistry packages, first MPQC and later PSI3. In recent years however, two respected quantum chemistry codes have been open sourced and are now available in Debian: ACESIII and NWChem. Make no mistake, those are not recently started codes or some Ph.D.'s pet-project but state-of-the-art projects targeted at massively parallel supercomputers and developed at the University of Florida's Quantum Chemistry Project (QTP) in the case of ACESIII and at Pacific Northwest National Laboratory (PNNL) for NWChem.

While ACESIII has a somewhat narrow focus on Coupled-Cluster (unfortunately, the current version does not yet implement analytic gradients for the "golden standard" CCSD(T) method) and Multi-Body Perturbation Theory methods, NWChem is a very versatile package supporting a variety of molecular quantum chemistry methods (including Density Functional Theory (DFT)), as well as periodic plane-wave electronic structure and (ab-initio and classical) molecular dynamics. At this point, NWChem probably covers 90% of all use cases for routine computational chemistry compared to the popular non-free codes Gaussian and GAMESS, while likely exhibiting superior parallel scaling at least compared to Gaussian.

Over the last year, I have packaged and integrated NWChem and ACESIII for Debian, and they are now both in testing. Furthermore, I have recently overhauled the packaging of MPQC and enabled parallel execution via MPI. Further, both MPQC and PSI will see updated versions (MPQC3 and PSI4) in the near future with significant increased functionality, including some unique (at least among open source codes) features like Symmetry-Adapted Perturbation Theory (SAPT) for PSI4 and general explicitly correlated corrections ([2]f12) for MPQC3. Unfortunately, they both did not get released in time for the wheezy freeze.

On the periodic/plane-wave front, I have also packaged and uploaded Quantum ESPRESSO (formerly PwSCF), a set of plane-wave programs, and I have been working with lafur Jens Sigur sson to get the latest Abinit release packaged. The nanoscale-physics team is also targeting further periodic ab-initio packages like BigDFT and Octopus, but those as well did not land in time for the freeze.

Finally, I also packaged and uploaded CP2K, a well-engineered and versatile periodic plane-wave/pseudo-potential code which focuses on state-of-the-art ab-initio Molecular Dynamics (AIMD) using Density Functional Theory. Some of the authors have recently published a paper reporting linear scaling benchmark calculations on a system with a million atoms using almost 50,000 CPU cores.

All of the above mentioned packages are included either in the molecular ab-initio or the periodic ab-initio Debichem tasks.

Stefano Zacchiroli: bits from the DPL for June 2012

Monthly DPL bits, fresh from the oven^W^W^W hot from DebConf12, and just posted to d-d-a.
Howdy from DebConf12. It's hot, but it's also time to bother you again with a (not so) brief DPL activity report, this time for June 2012. Time-based freeze: DONE, short freeze: TODO Two highlights for this month. First, you've probably noticed Wheezy is now frozen, YAY. This is huge achievement for the release, but also for the project. It's the first time we do a time-based freeze, and it took some quite heated discussion at the beginning of the release cycle to decide to do this. And we did it properly: respecting the planned month and narrowing down the period later. This exercise has hopefully helped both DDs in their package planning and our upstreams in targeting Wheezy with stable releases of their software. Kudos to the release team for their coordination work! Now we've the second part still TODO: releasing Wheezy, without RC bugs, with a freeze period as short as possible. See the beginning of my last "bits from the DPL" mail for my usual song and dance :-P on how to deliver that, together. DebConf12 A lot of us will attend DebConf12. Enjoy it! ... and take the chance to both have fun and make great plans for Debian's future. But remember that "if it didn't happen on a mailing list, it didn't happen". Not all of us will be lucky enough to attend DebConf (in person or remotely). Make sure that those who don't can take part in your team decisions and get informed of what is going to happen here. Politics Zack's spring tour I spent a significant part of June doing Debian talks ins some sort of "spring tour" between Italy and France. In particular: Many thanks to the organizers of these events for inviting and sponsoring me (as well as other Debian people, in the ESRF case) and for their interest in Debian. Sprints Assets Discussions Some relevant discussions for project evolution has been going on in June and I took part into them. You might want to have a look at them: Misc Cheers.
PS the boring day-to-day activity log for June is available at master:/srv/leader/news/bits-from-the-DPL.txt.201206

2 July 2012

Dominique Dumont: Kerberos configuration editor looking for a maintainer

Hello A while ago, Peter Knowles wrote a configuration model for Kerberos. Unfortunately, his priorities shifted before he completed this work. He was kind enough to send me the prototype in hope someone could take over. Although I do not know Kerberos, I believe the model is rather complete. Just click on the image below to judge for yourself: Class diagram of Kerberos configuration model This work was released under a LGPL-2+ license. There are some tasks left to get a Kerberos configuration editor. These are mentioned in config-model-kerberos readme file. To look at the code, just clone config-model-kerberos with
git://github.com/dod38fr/config-model-kerberos.git
If you need more information on Config::Model, see: If you are interested in adopting Kerberos model, please keep us informed on config-model-users at lists.sourceforge.net. This will avoid duplicated work. On my side, I ll gladly answer questions related to Config::Model to help you get started. All the best
Tagged: Config::Model, Kerberos, Perl

Michal &#268;iha&#345;: Surprising uses of Weblate

When I wrote Weblate I expected that major use cases will be free software projects, which will use it for public translating service. At least this was my intention for it. But I seem to be wrong, at least for now. Most of people who contact me regarding Weblate are doing private installations and I already know few places where it was massively used. Unfortunately most of them rejected to be publicly mentioned, so I can't tell you the names. But they do exist :-). Anyway I hope for some free software projects to adopt Weblate as well, otherwise I should have written it as commercial software :-)

Filed under: English Weblate 6 comments Flattr this!

Rapha&#235;l Hertzog: My Debian Activities in June 2012

This is my monthly summary of my Debian related activities. If you re among the people who made a donation to support my work (168.12 , thanks everybody!), then you can learn how I spent your money. Otherwise it s just an interesting status update on my various projects. Dpkg This month, I resumed my work on dpkg. I concentrated my efforts on some polishing of the 3.0 (quilt) format. With the latest version (1.16.6 which was uploaded to unstable shortly before the freeze), dpkg-source restores the source tree in a clean state after a failed patch application (#652970), doesn t overwrite the patch header from the pre-existing automatic patch, updates automatically debian/source/include-binaries during dpkg-source commit, and supports a new no-unapply-patches option for those who dislike the auto-unapplication at the end of the process when the patches were not applied at the start. I wanted to go further and offer a new feature that could insert the automatic patch at the bottom of the quilt series but I have been short on time to complete this feature. I just managed to factorize all the quilt handling in a dedicated Perl module (Dpkg::Source::Quilt) to have cleaner code in the module handling the source format (Dpkg::Source::Package::V3::quilt). For those who wonder, this feature is meant primarily for the X Strike Force team which maintains packages in Git and are doings lots of upstream cherry-picks (to fix regressions, etc.). But they also use quilt on top of that tree to keep some lasting Debian specific changes. With the 1.0 format, the automatic diff is a bit messy but at least it gets smaller automatically when a new upstream release gets out, there s nothing to clean out. I d like them to be able to use 3.0 (quilt) while keeping their workflow. I m leaning towards allowing --auto-commit=first:cherry-picks that would name the automatic patch cherry-picks and put it in the first position in the quilt series. (Opinions welcome on that feature, BTW) Packaging There s been quite some packaging in this last month before the freeze: While doing all this packaging work, I found 2 possible improvements that I filed as bug reports: Debian France Booth at Solutions Linux From June 19th to June 21th, I manned the Debian France booth at Solutions Linux together with Carl Chenet, Tanguy Ortolo and other members of the association. We answered lots of questions, sold all t-shirts and umbrellas that Carl imported from Germany and Switzerland (we really need to get our own merchandising stuff produced in France!), got people to join the association. We also presented a printed copy of the Debian Administrator s Handbook and of the corresponding French book. You can see Carl, me and Tanguy on this picture (click on it to see a bigger picture, thanks to S bastien Dubois of Evolix for this one!):
I know lots of people are preparing for Debconf but I decided to not attend this year, the price of the air plane ticket was a bit too hefty for me and it was also in partial conflict with our family vacations. I thought about attending the Libre Software Meeting instead but alas I won t go there either (but Roland Mas will be there!), I have too much work to complete before my own vacation in 2 weeks. Thanks See you next month for a new summary of my activities.

2 comments Liked this article? Click here. My blog is Flattr-enabled.

Johannes Schauer: port bootstrap build-ordering tool report 3

A copy of this post is sent to soc-coordination@lists.alioth.debian.org as well as to debian-bootstrap@lists.mister-muffin.de.

Diary

June 18 Pietro suggests a faster way to generate installation sets for a list of packages. In my case, I need an installation set for every source package in the archive to find out how often a binary package is needed to build a source package. As a result, the speed is doubled in contrast to the original approach.

June 19
  • adapt code to work with new dose release 3.0
  • remove unneeded parts of code
  • add different possibilities to find amount of source packages that need a binary package
  • add code to get multiple installation sets using Depsolver_int.solve

June 20
  • add ~global_constraints:false to Depsolver.listcheck, Depsolver.trim and Depsolver.edos_install calls
  • adapt output graph to limited xdot capabilities

June 21 I formulate an email to the list, reporting of dependency graphs of debhelper, cdbs, pkg-config and libgtk2.0-dev. My current technique gets an installation set for a source package, removes all those that are already installable and adds the others as a dependency of that source package. This dependency will include an installation set of that binary as well minus all packages that are already available. The problem with that approach are dependency cycles created by long dependency chains. Example: src:A needs B needs C needs A. B and C would both be added as a dependency of src:A. B as well as C would also include their installation set which in both cases includes A. So now there are two cycles: src:A->B->A and src:A->C->A. For a real life example, look at the following situation of cdbs and src:sqlite3. cdbs old situation It is created because src:sqlite3 needs cdbs needs python-scour needs python needs python2.7 needs libsqlite3-0. Therfor libsqlite3-0 is in the installation set of cdbs, python-scour, python and python2.7. This creates five cycles in the graph even though there is only one. It would be better to reduce the dependencies added to src:sqlite3 to its direct dependency which is cdbs. Package dependencies are disjunctions from which the solver chooses one or the other to build an installation set. To solve the problem above I would need to know which disjunction the solver chose and then only add the direct dependency of a package to the dependency graph.
  • improve build_compile_rounds performance
  • big overhaul of menu structure
  • fix subgraph extraction code

June 22
  • do not create a universe if not needed - use hashtables instead
  • for sorting packages, generating difference of package sets and otherwise comparing packages, always use CudfAdd.compare
  • as a custom list membership function, use List.exists instead of trying List.find
  • more speedup for build_compile_rounds
  • the number of source packages that can be built does NOT include the cross built packages
  • print closure members in graph
  • refactor code and move common functions to bootstrapCommon.ml
  • add breakcycles.ml for future code to break cycles using staged build dependencies
  • use more extlib functionality
  • extended package list input format

June 23 After several emails with Pietro I learn about syntactic dependency graphs. To document my progress and prove my efforts I committed the code as commit 6684c13. But this code was soon found out to be unecessary so it will be removed later and just serves as documentation.

June 24 I came up with another (better?) solution to get the chosen disjunctions. It simply uses the calculated installation set to decide for each disjunction which one was taken by the solver. I reported that important step and the open questions involved with it in an email to the list. The problem always was, that an installation set can easily contain more than one package of a disjunction. In this case it is not clear which branch was chosen by the solver. I found, that in Ubuntu Natty there are only 6 such packages and for each of them the situation can be solved. It can be solved because in all of those cases it is that either one package of a disjunction provides the other or that both packages depend upon each other, which means that both have to be included.

June 27
  • use installation set to flatten build dependencies of source packages
  • refactor code and move common functions to bootstrapCommon.ml

June 25 I have to have an algorithm that finds all circuits in a given graph. This is necessary so that:
  1. cycles can be enumerated for huge dependency graphs where cycles are hard to see
  2. cycles can be enumerated to find a cycle that can be broken using staged build dependencies
It seems that Johnson's algorithm is the best way to do this complexity wise and Pietro already blogged about the problem together with an implementation of the algorithm in ocaml. Unfortunately it turns out that his code doesnt implement the algorithm correctly and hence misses out on some cycles. The fix seems not to be too trivial so I'm still investigating it.

June 28
  • add crosseverything.ml to obtain a list of source packages that, if cross compiled, would make the whole archive available

Results While the first week was productive as usual, I had to work some time on a University project during the second week as well as attend a family meeting. I will catch up with the lost time over the course of the next week.

dose3 Using dose 3.0 (which fixes a bug about essential packages) the output of the algorithms is now likely less wrong then before.

performance Performance was improved in the generation of installation sets as well as in the code that tries out how many packages can be built in multiple rounds. This was achieved by more caching, less unnecessary operations in looping constructs, replacing lists with hashtables, not creating universes where not necessary.

user interface The main program, basenocycles.ml now has a much better menu structure.

input format The programs take two package file inputs. The list of source packages that has to be cross built for a minimal build system and the list of source packages that was chosen to be cross compiled in addition to that. Both files list one source package per line and now allow comments.

refactoring As more and more scripts are added, more and more functionality is moved to bootstrapCommon.ml which makes each script much cleaner.

what to test for cross building As discussed in the "Future" section of the last report, I now automated the process of finding out which packages, if they were cross compiled, would make the whole archive available because they break all cycles and allow native compilation of the rest. The outcome: to build 3333 out of 3339 packages in natty natively, at most 186 source packages must be cross compiled. The other six cannot be compiled because of version mismatches in the Natty Sources.bz2 and Packages.bz2. The code can be run from crosseverything.ml.

limit source dependencies to direct dependencies Reducing the dependencies of source packages from their full installation set to their direct dependencies by finding out which disjunction of their dependency list were taken, greatly simplifies the dependency graphs. The dependency graph created for libgtk2.0-dev could be reduced from 491 to 247 vertices for a depth of three. For cdbs it is now clearly visible that cdbs depends on libsqlite3-0 which builds from src:sqlite3 which depends on cdbs. Before: cdbs old situation After: cdbs new situation For pkg-config the graph also has been reduced to the one single cycle that matters: src:pkg-config needs libglib2.0-dev which depends on pkg-config which builds from src:pkg-config. Before: pkg-config old situation After: pkg-config old situation

Future I will prepare content for wookey's debconf talk on crossbuilding and bootstrapping. As this will include directions how to use the current code, I will kill two birds with one stone and write some proper documentation for my current source. The following two lists will be displayed after a dependency graph is calculated and reduced to its scc:
  • those source packages that have the least build dependencies not fulfilled. Those might be candidates for easy staged build dependencies. Since the source package is part of the scc, it will definitely be involved in some cycle somewhere.
  • those binary packages that most source packages depend upon. Those could be candidates for cross compilation as it might be easier to cross compile the source package than using staged build dependencies.
Patrick managed to cross build packages with sbuild now. So the list of packages that crosseverything.ml produces can now be checked efficiently for cross buildability. With this list, potentially more cycles can be broken out of the box. A feature will be added that allows the user to remove all packages from a dependency graph that can be cross compiled without any additional effort. Version mismatches between source and binary packages in Sources.bz2 and Packages.bz2 respectively in Ubuntu make the scripts fail and/or produce wrong results. Debian (even Sid) doesnt have this problem so I should find out where to report this problem to Ubuntu. I need to write a working version of Johnson's algorithm because much functionality depends upon it. I have the option to improve Pietro's version or write one from scratch. Writing one from scratch might be easier as I have Pietro's code as template as well as a Java implementation of Johnson's algorithm which seems to work. The following functionalities need working cycle enumeration:
  • given source packages with staged build dependencies, an enumeration of cycles is needed to find out which cycles can be broken by building packages staged. It makes less sense to blindly build a package stage and then check if this makes more packages available.
  • display cycles of a dependency graph to the user. After obtaining all cycles in the graph it makes sense to sort them by their length. The user would then investigate the situation of the smallest cycles first. This makes sense because breaking small cycles can potentially break bigger cycles. Since in the end, all cycles have to be eliminated anyway, it makes sense for the user to first tackle the small ones.
  • display the feedback arc set to the user. The packages in the feedback arc set might be very good candidates for reduced build dependencies or cross compilation.

30 June 2012

Bernhard R. Link: ACPI power button for the rest of us

The acpi-support maintainer unfortunately decided 2012-06-21 that having some script installed by a package to cleanly shut down the computer should not be possible without having consolekit and thus dbus installed. So (assuming this package will migrate to wheezy which it most likely will tomorrow) with wheezy you will either have to write your own event script or install consolekit and dbus everywhere. You need two files. You need one in /etc/acpi/events/, for example a /etc/acpi/events/powerbtn:
event=button[ /]power
action=/etc/acpi/powerbtn.sh
Which causes a power-button even to call a script /etc/acpi/powerbtn.sh, which you of course also need:
#!/bin/sh
/sbin/shutdown -h -P now "Power button pressed"
You can also name it differently, but /etc/acpi/powerbtn.sh has the advantage that the script from acpi-support-base (in case it was only removed and not purged) does not call shutdown itself if it is there. (And do not forget to restart acpid, otherwise it does not know about your event script yet). For those too lazy I've also prepared a package acpi-support-minimal, which only contains those scripts (and a postinst to restart acpid to bring it into effect with installation), which can be get via apt-get using
deb http://people.debian.org/~brlink/acpi-minimal wheezy-acpi-minimal main
deb-src http://people.debian.org/~brlink/acpi-minimal wheezy-acpi-minimal main
or directly from http://people.debian.org/~brlink/acpi-minimal/pool/main/a/acpi-support-minimal/. Sadly the acpi-support maintainer sees no issue at all and ftp-master doesn't like so tiny packages (which is understandable but means the solution is more than a apt-get away).

26 June 2012

Michal &#268;iha&#345;: Migrating content

I seem to have spend too much time online and used too much of blogging engines. Yesterday, I've completed yet another import of content to this blog, to have all my content available in single place. Looking at the import scripts I already have four of them - Movabletype, Nanoblogger, Wordpress and recent addition was Drupal. For Drupal, I had to install Node export module to have some sensible way to get the content. Then it was just matter of parsing XML and fixing up links. Quite challenging was rendering of Texy! markup in Python as there seem to no native solution available. Fortunately there is a XML-RPC service available, what made that part quite easy.

Filed under: English Website 0 comments Flattr this!

Russ Allbery: Review: Quiet

Review: Quiet, by Susan Cain
Publisher: Crown
Copyright: 2012
ISBN: 0-307-45220-4
Format: Kindle
Pages: 263
I've always been an introvert. This is something that surprises some people when they first meet me since they equate introversion with shyness, and I'm not at all shy. It surprises others because I'm quite vocal and outspoken in meetings, but introversion also doesn't imply a lack of self-confidence. I can run meetings, give presentations, and argue my perspective in front of just about anyone, but I don't like parties, I crave time by myself, and I could happily go for weeks without seeing another human being. I'm an introvert because I find people draining rather than invigorating, written communication far easier and more comfortable than spoken, and superficial social contact more irritating and frustrating than enjoyable. If you think think that means there may be something wrong with me, or that I would be happier if "drawn out of my shell," I wish you would read this book. But I suspect its core audience will be people like me: those who are tired of being pushed to conform with extrovert beliefs about social interaction, those who are deeply disgusted by the word "antisocial" or feel pangs of irrational guilt when hearing it, or those who just want to read an examination of interpersonal interactions that, for once, is written by and about people who like quiet and solitude just like they do. I first encountered Susan Cain via her TED talk, which I think is both the best possible summary of this book and the best advertisement for it. If you've not already seen it, watch it; it's one of the best TED talks I've seen, good enough that I've watched it three times. If you then want more of the same, buy Quiet. Quiet has, I think, three messages. First, it's a tour of the science: what is introversion and extroversion? Is there evidence that these are real physiological differences? (Spoiler: yes.) What do we know about introversion? How do we know those things what experiments have been done and what methods have been used? Here, it's a good general introduction, although Cain is careful to point out that it only scratches the surface and there's much more scientific depth. For example, she touches on the connections between introversion and sensitivity to stimulus and points out that they're two separate, if related, categorizations, but doesn't have the space here to clarify the distinctions and tease them apart. But she lays a reasonable foundation, particularly in defense of introversion as a natural, physiologically grounded, scientifically analyzable, common, and healthy way of interacting with the world. (For those who are curious about the distinctions between introversion and sensitivity, and the argument that most of what Cain says here about introversion is actually about sensitivity, see the blog post by Elaine Aron.) The second message, the one that resonated with me the most, was Cain's passionate defense of introversion. Business culture (at least in the United States, which is what both Cain and I know) is strongly biased towards extroversion; at least faking extroversion seems to be required for some career advancement. Extrovert culture dominates politics and most public discourse. It's common to find people who consider introversion, particularly in children, to be a sign of unhappiness, poor social adjustment, psychological problems, or other issues that should be "cured" or changed. Cain's gentle but firm passion in defense of introversion is a breath of fresh air. She attacks open plan offices, the current obsession with group learning and social school settings, and the modern group-think bias towards collaboration over solitude and concentration, and she does that with a combination of polite frustration and the conclusions of multiple studies. Introverts will be cheering as she constructs solid arguments and musters evidence against things that we've always found miserable and then been told we were wrong, short-sighted, or socially inept for finding miserable. I am so utterly on her side in this argument that I have no way of knowing how persuasive it will be, but it's lovely just to hear someone put into words what I feel. This defense does skew the book. Quiet is not, and does not purport to be, an even-handed presentation of introversion and extroversion. It's written proudly and unabashedly from the introvert's point of view. I'm fine with that: I, like Cain, think the US is saturated in extrovert perspectives and extrovert advice, particularly in the business world, and could use some balancing by activism from the other perspective. But be aware that this is not the book to look to for an objective study of all angles of the introvert/extrovert dichotomy, and I'm not sure her descriptions of extroversion are entirely fair or analogous to those of introversion. The extroversion described here seems somewhat extreme to me. I'm dubious how many extroverts would recognize themselves in it, which partly undermines the argument. The third message of the book, once Cain has won the introvert's heart, is some advice on how to be a proud introvert, to make the space and find the quiet that one desires, and to balance that against places where one may want and need to act like an extrovert for a while. Cain thankfully does not try to make this too much of the book, nor does she hold up any particular approach as The Answer. All the answers are going to be individual. But she does offer some food for thought, particularly around how to be conscious of and make delibrate choices about one's energy expenditures and one's recharge space. She also captures beautifully something that I've not seen explained this well before: the relief that an introvert can feel in the company of an extrovert who helps navigate social situations, make conversation, and keep discussions going until they can reach the depth and comfort level where the introvert can engage. I wish anyone in a position of authority over social situations would read this book, or at least watch the TED talk and be aware of the issues. Particularly managers, since (at least in my relatively limited experience) workplace culture is so far skewed towards extroversion that it can be toxic to introverts. Many of the techniques used by extrovert managers, and the goals and advice they give their employees, are simply wrong for introverts, and even damaging. Cain speaks well to the difficulties of empathy between people with very different interaction preferences, such as the problems with extroverts trying to "draw out" introverts who have hit social overload (or sensitive people who have hit stimulus overload). She also discusses something that I'd previously not thought about, namely how the pressure towards extroversion leads people to act extroverted even when naturally introverted, and how it's therefore very difficult to tell from behavior (and sometimes even to tell internally!) what one's natural interaction style is. But mostly I recommend this book if you're an introvert, if the TED talk linked above speaks to you. Even if we can't convince the world to respect introversion more, or at least stop treating it as abnormal, it's a lovely feeling to read a book from someone who gets it. Who understands. Who fills a book with great stories about introverts and how they construct their worlds and create quiet space in which to be themselves. Rating: 9 out of 10

24 June 2012

Pablo Lorenzzoni: Zotero and note-taking

I was looking for an excuse to try Zotero and the perfect opportunity appeared when I got a whole lot of references to group for a month of Magnetic Ressonance studies I am currently taking. I was also pleased to notice it is packaged to Debian. I am used to note-taking software. Back when I used a Palm m130 (and a Treo 650), I managed a lot of Memos I eventually migrated to Note-Everything in my current Android phone. Zotero, unfortunatelly, is not interfaceable with my phone (or I was still unable to figure out how to do so), but it s powerful in managing references beyond simple note-taking. Is anyone using Zotero in a more ambitious way? I ve read about people using it to keep large researchs to support fiction and non-fiction book-writing I also watched some YouTube videos on it. As far as I went with it, Zotero might become an important piece in my toolbox wrt reference keeping, so I was just trying to figure out how many other niches it can fill

21 June 2012

John Goerzen: I introduced my 5-year-old and 2-year-old to startx and xmonad. They re DELIGHTED!

Two years ago, Jacob (then 3) and I built his first computer together. I installed Debian on it, but never put a GUI on the thing. It s command-line, and has provided lots of enjoyment off and on over the last couple of years. I ve written extensively about what our boys like to do, and the delight they have at learning things on the command line. The looks of shock I get from people when I explain, as if it s perfectly natural, that my child has been able to log in by himself to a Linux shell since age 3, are amusing and astounding. Especially considering that it is really not that hard. Instead of learning how to run an Xbox, he s learned how to run bash. I like that. Lately, Jacob (now 5) hasn t been spending much time with it. He isn t really at a stage where he wants to push his limits too far, I think, but yet also gets bored with the familiar. So I thought it was time to introduce a GUI in a limited fashion, perhaps to let him download photos and video from his Vtech toy camera (that takes real low-res photos and videos which can be downloaded over a USB1 link). He s familiar with the concept, at least somewhat, having seen GUIs on Terah s computer (Gnome 2) and mine (xfce4 + xmonad). So last night, Oliver (age 2) and I went down to the basement on a mouse-finding expedition. Sure enough, I had an old PS/2 mouse down there that would work fine. The boys both helped string it through the desk up on our play room, and were tremendously excited to see the red light underneath it when the computer came on. Barely able to contain the excitement, really. A bit like I remember being when I got my first mouse (at a bit of an older age, I suppose.) I helped him them in as root for the very first time. (Jacob typed root , and I typed the password, and provided the explanation for why we were telling the computer we were root .) Jacob and Oliver alternated typing bits of some apt-get command lines. Then while we waited for software to download, I had to answer repeated questions of how soon will the mouse work? and what does install mean? Finally it was there, and I told Jacob to type startx. I intentionally did not install a display manager; more on that later. He pressed Enter, the screen went blank for about 5 seconds, and then X appeared. Excited can t begin to describe how they acted. They took turns playing with the mouse. They loved how the trash can icon (I started with XFCE) showed trash IN the trash can. But they are just learning the mouse, and there s a lot about a typical GUI that is unfriendly to someone that isn t yet proficient with a mouse. The close buttons are disappointingly small, things can be too easily dragged on and off the panel and menus. When I sat down to think about it, the typical GUI design does not present a very good it always works the same interface that would be good for a child. And then it occurred to me: the perfect GUI for a child would be simply xmonad (a tiling window manager that can be controlled almost entirely by keyboard and has no need for mouse movements in most cases.) No desktop environment, no file manager in the root window. Just a window manager in the classic X way. Of course! So after the boys were in bed, I installed xmonad. I gave Jacob s account a simple .xsession that starts a terminal and xmonad. Today, Jacob informed me that he wanted his computer to look just like yours. Playing right into my hands, that was! But when he excitedly typed startx, he said it wasn t just like mine. Uh oh. Turns out he wanted the same wallpaper as my computer uses. Whew. We found it, I figured out that xli(1) loads it in the root window, and so I added a third line to .xsession. More delight unlocked! Jacob mastered the basics of xmonad really quickly. Alt-Shift-C to close a window. Alt-Shift-Q to quit back to the big black screen . Alt-Shift-Enter to get a terminal window. We launched thunar (the XFCE file manager) and plugged in his camera. He had a good deal of fun looking at photos and videos from it. But then I dropped the true highlight of the day for him: I offered to install Tuxpaint for him. That s probably his favorite program of all time. He watched impatiently as apt-get counted down 1m30s for tuxpaint and its libraries. Then we launched it, and he wanted to skip supper so he could keep playing Tuxpaint on my VERY OWN COMPUTER! I d been debating how to introduce GUIs for a very long time. It has not escaped my attention that children that used Commodores or TRS-80s or DOS knew a lot more about how their computers worked, on average, than those of the same age that use Windows or MacOS. I didn t want our boys to skip an entire phase of learning how their technology works. I am pleased with this solution; they still run commands to launch things, yet get to play with more than text-based programs. At bedtime, Jacob asked me, very seriously: Dad, how do I start tuxpaint again? First you log in and type startx. Then you can use the mouse. Jacob nods, a contemplative look on his face.. Then, I continue, you type tuxpaint in the terminal, and it comes right up. Jacob nodded very seriously a second time, as if committing this very important information to long-term memory. Then gave a single excited clap, yelled Great! , and dashed off.

Next.

Previous.