Back from Qt Dev Days, first Qt projects

I’ve actually been back close to a week now, but never mind that…

In the per-conference day with training sessions I attended the Qt Essentials track, which was more or less as expected. Glad I read a full Qt book beforehand, it would have been challenging to keep up with the shear amount of information without it.
The keynotes I attended on the second day were not particularly exciting: no major announcements nor insights were given. The technical talks on the other hand were filled with goodies. The talks by Jens Bache-Wiig and Roberto Raggi on Qt Quick were especially good.*

The talks definitely made me want to try Qt Quick for doing user interfaces for small-form factor devices, especially because it allows for very rapid prototyping and iterations when developing. The current lack of widgets and traditional layouts probably limits its usefulness for typical desktop application with more complex user interfaces though. There is nothing that helps you achieve a native look and feel either, but the Qt Components project is aiming to bridge those gaps.
I also suspect that the declarative and dynamic nature of QML poses several new challenges for developers, especially for those that are mostly used to traditional Qt programming with C++. I’m especially concerned that there was no way to visualize or do static checking on the property-bindings that are so central in QML. Very curious as to how that plays out in practice.

*I’m told the talks will be online after the Qt Developer Days event in San Fransisco is over.

Qt projects you said?

Going forward I’ll be doing some projects with Qt, in the same way I have done with GTK. My first project has already started: implementing viewer-class OpenRaster support for Qt. This means that applications using Qt and QImage will soon be able to display fully-rendered OpenRaster images!
Development of the Qt integration happens in the repository on gitorious, and the libora modifications currently lives in my personal clone. It will be pushed to mainline as soon as I have more-or-less settled on the API, and done a basic implementation. Using libora for all the OpenRaster specific stuff is being a bit more painful than expected, but it is the right thing to do as it means that other consumers benefits as well. Like a potential GdkPixbuf plugin or applications not using Qt or GTK. I’ll write more once it reaches a useful state.

After that is done I will probably do something with more UI, like a proper application. Hopefully I will get to toss Qt Quick into the mix as well. I’ve got an idea that I think would be a nice fit, so we’ll see.

Proprietary platforms, free software and contributors

While I do not believe that killer applications exist, I do like to think that free and open source software applications adds value to the platform it supports, and its users. For small applications it might not be much, but still non-zero.
Personally, I do not particularly want to add value to proprietary platforms. I do not use them, nor want to “endorse” them. This is especially so if it means giving less to free platforms or software: I would rather spend my time on developing new features and fixing bugs in my favorite free software applications than to spend it on packaging and support for Windows, for example.

But at the same time I want to add value to free software as a whole and I recognize that getting the  software out to the user is fundamental. And that proprietary platforms like Microsoft Windows and Mac OS X have a ten to hundred times bigger user-base than free platforms like GNU/Linux. So time spent there would potentially be worth a lot, right? Yet I do not really want to do it, and I think that many existing free software contributors feel the same…

It is paradoxical that Windows and OSX represents the largest user-bases, often also for free and open source software, yet one of the smallest contributor-bases. How can this be fixed? How can we get more of the people that seemingly care about free and open source software on proprietary platforms to actually contribute?

MassifG 0.2.2

Another day, another release. This release fixes:

  • Missing axis labels – now it is explicit what each axis represents
  • Inconsistencies with GNOME HIG: Button ordering in save/open dialog and missing ellipsis for menu actions which require further user input
  • A error message on canceling in the save dialog which should not have been there

Ubuntu 10.04 packages are now in the Openismus PPA. Due to scheduled downtime for Launchpad it might take an hour or two before they are built. The tarball is here, Fedora 13 packages here (i686, x86_64). Arch packages are still in AUR, and Gentoo packages in Dave’s overlay.

I’ve updated the README to include information about the roadmap and tasks to be done. Check it out if you’re interested in improving this small tool.
Hopefully there will be a massifg product in GNOME bugzilla soon (I’ve made a request), but in the meantime just report problems to me by email.

Here is yet another screenshot:
2010-09-09-122757_1680x1050_scrot

MassifG 0.2.1; now packaged for your favorite distro*

*if your favorite distro is Fedora, Ubuntu, Arch or Gentoo.

This is a bugfixes-only release, and fixes regressions in print/save functionality (which rendered 0.2 kinda useless, thus the quick point release) and a parsing bug on 32-bit platforms. Behavior of the open/save dialog has also been improved. Tarball is here.

Packages:

I’ve pushed the package files for Fedora and Ubuntu to a branch in case anyone wants them. The packages should require little to no adaption to work on earlier distro versions than the tested ones. The Ubuntu package should also work fine on Debian. With time I might work to get the packages into the official repositories, but that is not a priority at the moment.

MassifG 0.2

MassifG is an application for visualizing the output of valgrinds massif tool. See the first release announcement for more info. Here is the high level list of changes since version 0.1:

  • Graphing component ported to use GOffice – graphs are much nicer now
  • A detailed view has been implemented
  • Parses the heap trees found in massif snapshots
  • Menu entry for directly exporting graph to a PNG file
  • gtk-doc based API documentation

Of course there were also many minor changes, fixes and improvements. Here is how it looks now (simple and detailed view, respectively):

massifg-0.2-simplemassifg-0.2-detailed

The tarball can be found here. Packages for Arch are in AUR. I’m also hoping to make packages for Ubuntu and Fedora in the next couple of days.

Roadmap

I will probably move my focus over to C++ and other tasks now, so MassifG progress will be slower, but here is what I’d like to see going forward.

  • Show name of the function when hovering over the graph.
    Minor thing, but it will increase usability a lot as it can be very hard to see which legend entry the data corresponds to in the detailed view. Requires support in GOffice
  • Add axis labels and title with information from the massif file.
  • Improve usability on small screen/window size.
  • The detailed view currently needs a lot of space, and does not work nicely when this is not available. Need to ask the GOffice people for some hints and tips here.
  • Make an API and UI for running massif.
    This so that users don’t have to invoke massif manually, and then open the file in MassifG to visualize the results. Would additionally be nice if the graph was updated interactively while massif runs, but that is secondary.
  • Make a UI widget for visualizing the heap tree.
    Possibly a GtkTreeView. I’m open for suggestions here.
  • Expose a public library with the relevant parts of the API.
    This way, others applications can use it – if anyone is interested I’d love to have some feedback on the API. I am of course open to changing it if necessary. Support for GObject introspection would be nice too.

If anyone would like to work on any of this, give me a hint so we don’t duplicate effort. Let me know if you have any other good ideas too.

Determining physical topology of hotplugged USB devices with udev

As part of a bigger project of mine, I wanted to answer the following questions: How can one tell which physical port a hotplugged usb-device is plugged into on Linux? Can one do this when the device is plugged into an usb-hub (i.e: non-root hub) too? Since this is potentially useful to others out there, I share my findings here.

The usual “lsusb” or “lsusb -v” gives no indication that the kernel knows about the physical topology of the devices connected to an USB bus. However “lsusb -t” does indeed show the topology, so the kernel does know about it and make this info available to user-space. So, how to use this in udev? Prodding some USB storage class devices with udevinfo, shows that there is no attribute that gives this information directly. But, the DEVPATH attribute for USB devices actually contains this information.

For instance, an USB mass storage device connected to port 2 of the root-hub with bus number 2 has the following devpath: “/devices/pci0000:00/0000:00:1d.7/usb2/2-2/2-2:1.0/host12/target12:0:0/12:0:0:0/block/sdb” and a USB mass storage device connected to port 5 of the root-hub with bus number 1 has the devpath “/devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/block/sdb”. It becomes a bit confusing when there are USB hubs involved: “/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1.1/2-1.1.1/2-1.1.1:1.0/host16/target16:0:0/16:0:0:0/block/sdb” refers to a device plugged into port 1 of an USB hub plugged into port 1 of a second hub which is plugged into port 1 of the root-hub with bus number 2.

We see that in all cases the information about the physical topology is in the substring just before “:1.0”; “2-2”, “1-5” and “2-1.1.1”, respectively for the given examples. And that the format is “$busnumber-$port” for the simple case of connecting the device directly to the root-hub, and $busnumber-$port1.$port2  ->   .$portN for the general case, with N-1 usb-hubs between the device and the root-hub.

Just to show that this works, here is a quick and dirty udev rule and helper python script which parses the devpath and creates a symlink to the first partition of a USB mass storage device under /dev/usb based on the bus and port the device is connected to. Results might look like this:

tree /dev/usb/                                                                    Thu Jul 29 17:34:38 2010

/dev/usb/
`-- 2
    `-- 2
        |-- 2 -> ../../../sdc1
        `-- 4
            `-- 4 -> ../../../../sdb1

A more useful thing to do might for instance be passing through all devices connected to a certain physical usb-port to a certain virtual machine. Or maybe letting an embedded system responding differently to USB devices plugged into a physically secured root-hub than to one that is available to the user.

Introducing MassifG 0.1

MassifG is an application for visualizing the output of valgrinds massif tool. I am writing it as part of my trainee program here at Openismus. MassifG is free software, available under GPLv3. You will find the git repository at gitorious, and the tarball release for 0.1 here. Packages for Arch are available in AUR.

Used together with massif MassifG gives you a nice, simple graph of allocated heap memory over time which you can use to help evaluate if your program is leaking memory or not:

Current status

With release 0.1 MassifG can:MassifG 0.1

  • Parse and display a simple graph from massif output.
  • Open files selected on the command line or from the UI.
  • Print out the graph to a printer or file. This code was contributed by Murray Cumming – thanks!

I was hoping that I could make version 0.1 the “minimally useful” release, but I have to admit that it is not quite there yet. Instead I nickname release 0.1 “getting it out there”. The main issue is that there is massif output that breaks the graph, see under tests/ for an example.

Implementation

MassifG is written in C, and uses GTK+ for its graphical user interface. Once the ability to export the graph is implemented, it should be easy to allow the application to build and run without GTK, if anyone wants to do that.

The parser is a simple state-machine. It might have been wiser to use bison+flex, and I’ll reevaluate that when I need to implement parsing of the detailed output.

The graph functionality is implemented using Cairo and Pango. While Cairo and Pango are excellent technologies with nice APIs, they are quite low-level and that means having to care about all the details. As that brings no benefit to this application I might rewrite the graphing functionality to use the goffice library instead. Sadly there seems to be little high-level or introductionary documentation to goffice APIs, so I might have to fix that along the way.

Roadmap

In the short term I will:

  • Implement parsing and graphing of the detailed massif output
  • Fix the graphing bug(s)
  • Add the ability to export/save a graph as PNG,PDF et.c. without having to go by the printing dialog

In the longer term I’m considering:

  • Adding the ability to run massif on a program directly from MassifG
  • An interactive mode which updates the graph while the program to be analyzed is still running
  • Making a custom widget which other applications can embed

In the meantime, please do give the current version some testing, and report bugs and other issues.

Hardware passthrough in LXC (or: running a desktop in a cgroup)

At home I have a physical server that runs as a virtualization host (with kvm, lxc, qemu, libvirt and nfs), while the actual services I use run in virtualized servers, mostly as LXC containers.

One of these runs MPD and outputs music to the sound card of the host in addition to a web stream that I can access from anywhere in the world. Since the host and guest are using the same kernel, passing the soundcard on to the guest was as simple as bind mounting /dev/snd of the host into the root filesystem of the guest. I’m not quite sure how ALSA handles concurrent access, but it could be that this also works if several guests (or the host+guests) are playing to the same device.

But what is required to have working Xorg inside a cgroup/lxc container? Can we just do something similar? Turns out we can. Basic Xorg with the vesa driver and the old style input (no hal input hotplugging) works if you bind mount in /dev/tty7 (or another tty), /dev/mem, /dev/dri and /dev/input. Here is the obligatory screenshot:

Xorg running on the host graphics card from within a cgroup

Xorg running on the host graphics card from within a cgroup

So whats my motivation for trying this out? Curiosity mostly, but in a multi-seat system it could be nice to have each seat run as separate OS in a lxc container. It would allow each seat to run different distributions (within certain limits) and make sure that resources (CPU time, memory) are distributed evenly. And to provide isolation for security reasons.

That we need access to /dev/mem is currently a deal breaker as far as security goes, because it means that whoever gains root access in one of the guests will have control over the host (and thus the other guests) because they can modify the physical memory. There has been some interest in running Xorg as a unprivileged user, and that might address this issue. Locking it down with SELinux or similar might also be possible.

Obviously for multiseat you will need multiple screens somehow, either by using multiple cards or by sharing a single card (using one output each). I don’t immediately see any reason why the former should pose any problems, and with Dave Airlies recent work on multiple X servers on a single card that might also be possible in combination with cgroups/lxc.

I plan to test that this also works with the Intel driver, and perhaps also the Nvidia propriatary one with time. And perhaps try to get input with hal hotplugging working.

LVM snapshot merging avaliable

After being asked by a user in #ubuntu-no on Freenode IRC if there was a method of restoring his system, I researched if the underlying things needed to implement this was present (always curious…). While LVM has had snapshots for a long time, being able to merge a snapshot back into its origin has been missing. Some 15 minutes of googling showed that initial work on this was done in August 2008, so strange if it hasn’t been completed yet? Turns out it has, so the strange part is that none of the Linux news sites have written about it (that I’ve seen).

The required kernel bit, a “merge target” in the DM layer, was merged in the just released linux 2.6.33 and the lvm parts are there from 2.02.58.  LVM can now do snapshot merging with lvconvert –merge! I’m assuming here that the device-mapper code thats in between those two components has also been finished and released, which ought to be a safe assumption.

This makes me wonder why Fedora has chosen to base their System Rollback feature for Fedora 13 on btrfs instead of LVM, which would work on any file-system. There are probably good reasons.