Wednesday, May 26, 2010

GTK merged XI2 support

From GNOME Bug 596725 - Add XInput2 support:
- Comment #11 from Matthias Clasen <...> 2010-05-26 00:07:29 +UTC ---
Merged


Nice!
Now I just need to find time to play with it...

Wednesday, March 3, 2010

Vodafone Australia mobile broadband and Fedora Linux

well, that title should get me a few hits :)

Anyway, the other day I had to set up one of these 3G mobile internet USB modems on a Fedora 12 box. The dongle in question was from Vodafone, purchased about a week and a half ago. It didn't work out of the box, though in hindsight it should have. So for anyone who's googling around on how to set this up (or whether it can be set up at all), here's the gist.

The dongle is a HUAWEI Technology usb modem, Vendor number 12d1, product id 1520. The modem looks like a mass storage device on account of the manufacturer trying to be smart. If you plug the modem in, dmesg has this to say:


usb 1-2: new high speed USB device using ehci_hcd and address 6
usb 1-2: New USB device found, idVendor=12d1, idProduct=1520
usb 1-2: New USB device strings: Mfr=3, Product=2, SerialNumber=0
usb 1-2: Product: HUAWEI Mobile
usb 1-2: Manufacturer: HUAWEI Technology
usb 1-2: configuration #1 chosen from 1 choice
scsi5 : SCSI emulation for USB Mass Storage devices
usb-storage: device found at 6
usb-storage: waiting for device to settle before scanning
usb-storage: device scan complete
scsi 5:0:0:0: CD-ROM Vodafone CD ROM (Huawei) 2.31 PQ: 0 ANSI: 2
sr1: scsi-1 drive
sr 5:0:0:0: Attached scsi CD-ROM sr1
sr 5:0:0:0: Attached scsi generic sg4 type 5


As I said above, these modems look like mass storage devices and need to be switched to the actual modem mode. The nifty program usb_modeswitch does exactly that, but alas, only in version 1.1.0 for this particular device. This version also includes the udev rules to make everything work automagically. At the time of writing, Fedora 12 didn't have 1.1.0 available yet (Bug 563503). So you can poke the maintainer to update the package (see the bug) or grep the spec file from that bug report and build the rpm yourself. Once built, install, plug the modem in and the dmesg looks a lot better:


usb 1-2: new high speed USB device using ehci_hcd and address 8
usb 1-2: New USB device found, idVendor=12d1, idProduct=1465
usb 1-2: New USB device strings: Mfr=3, Product=2, SerialNumber=0
usb 1-2: Product: HUAWEI Mobile
usb 1-2: Manufacturer: HUAWEI Technology
usb 1-2: configuration #1 chosen from 1 choice
scsi7 : SCSI emulation for USB Mass Storage devices
usb-storage: device found at 8
usb-storage: waiting for device to settle before scanning
scsi8 : SCSI emulation for USB Mass Storage devices
usb-storage: device found at 8
usb-storage: waiting for device to settle before scanning
usbcore: registered new interface driver usbserial
USB Serial support registered for generic
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial Driver core
USB Serial support registered for GSM modem (1-port)
usbcore: registered new interface driver option
option: v0.7.2:USB Driver for GSM modems
option 1-2:1.0: GSM modem (1-port) converter detected
usb 1-2: GSM modem (1-port) converter now attached to ttyUSB0
option 1-2:1.1: GSM modem (1-port) converter detected
usb 1-2: GSM modem (1-port) converter now attached to ttyUSB1
option 1-2:1.2: GSM modem (1-port) converter detected
usb 1-2: GSM modem (1-port) converter now attached to ttyUSB2
option 1-2:1.3: GSM modem (1-port) converter detected
usb 1-2: GSM modem (1-port) converter now attached to ttyUSB3
usb-storage: device scan complete
usb-storage: device scan complete
scsi 8:0:0:0: Direct-Access Vodafone Storage (Huawei) 2.31 PQ: 0 ANSI: 2
scsi 7:0:0:0: CD-ROM Vodafone CD ROM (Huawei) 2.31 PQ: 0 ANSI: 2
sd 8:0:0:0: Attached scsi generic sg4 type 0
sd 8:0:0:0: [sdd] Attached SCSI removable disk
sr1: scsi-1 drive
sr 7:0:0:0: Attached scsi CD-ROM sr1
sr 7:0:0:0: Attached scsi generic sg5 type 5


Whoopdi-doo. The modem is recognized as modem and we can go and set it up. Now, I don't get a warm fuzzy feeling when editing config files that I'll likely not look at again for a while, so I chose the clicky-pointy route: the magnificent NetworkManager. Click on the NM icon on your desktop, and it'll look like this:



Click on new connection, then jump through the wizard and you're done.










Now, all you have to do whenever you need to connect to the internet is plug the modem in, wait for a few seconds and then click onto your connection:




The sad thing is, that if usb_modeswitch 1.1.0 was installed already, it would have truly been plug and play, even though Vodafone claims that Linux is not supported. Oh well, at least this way I've got something to write about to shoo away those tumbleweeds on my blog.

Many thanks to Laurianne for letting my try the dongle on the Mac first (and letting me install the ridiculous piece of software Vodafone ships with the dongle) and Tom for running Debian which already was on usb_modeswitch 1.1.0 - showing that the modem works.

Tuesday, February 16, 2010

Fedora rawhide and X server input configuration

I've pushed the bits required to change from hal to udev for device discovery in the X server into rawhide today. Unfortunately, this means that existing configurations may break. Especially all custom fdi files will stop working as they merge their options into the information HAL provides to the server - but the server doesn't listen to HAL anymore. For the distribution-provided fdi files - they will move to the new format as packages are updated.

If you have fdi files in /etc/hal/fdi/policy/, please act now. We don't have a tool to automatically convert your custom fdi files into xorg.conf snippets, so unfortunately you'll have to do this manually. You can convert them now and leave the fdi files in place, they'll simply be ignored once the package is updated.

The new configuration format is the xorg.conf-style configuration with InputClasses. If you've updated already, the xorg.conf(5) manpage has more info or check out the Fedora wiki page for input device configuration.

Monday, January 4, 2010

New configuration world order

In the last couple of weeks, Dan Nicholson and Julien Cristau have been working on revamping the X server configuration and hotplugging code, introducing a couple of new features. This work is now pulled into master and brings about a new way of configuring the X server.

The three new features are:

  • udev backend support

  • Support for an xorg.conf.d configuration directory

  • Support for matching rules in the xorg.conf



udev backend support


Back in 2006, support for hotplugged input devices was added and up to server 1.7, the incarnation worked with HAL as the provider of the input devices.
HAL is now deprecated and - at least under Linux - replaced with udev. Julien wrote a new backend that queries udev instead of HAL but otherwise follows the same principle:
Upon startup the X server queries the active backend for the list of input devices and initializes them accordingly. When a new device is added at runtime, the server is notified and adds it at runtime. HAL and udev are mutually exclusive, so enabling one disables the other. Currently, udev is disabled by default though I'd like to see it being default for 1.8.

On that note, users still confuse HAL and evdev though they have little to nothing to do with each other. The same is of course valid for the udev backend.

xorg.conf.d support


Over recent years, the xorg.conf support has moved towards two overlapping goals - support partial xorg.conf's with the server filling in the rest and removing the need for an xorg.conf entirely.
For most installations the server now has the right defaults and is usable without any configuration file. For the few cases where it is needed, a single section is often enough.

However, one remaining problem was that the xorg.conf is a single file and not easy to programmatically edit. Dan has now added support for a directory-based configuration. Again, the principle is simple: in addition to the xorg.conf file (if it exists), the /etc/xorg.conf.d/**.conf files are read and parsed as well. It performs like expected, with a section being added just as if it was present in the xorg.conf. Hence, a possible configuration may be:


:: whot@barra:~> ls -R /etc/xorg*
/etc/xorg.conf

/etc/xorg.conf.d:
10-synaptics.conf 97-wacom.conf 99-evdev.conf


Note that the xorg.conf is parsed before the xorg.conf.d, hence it always has precedence. This allows for distributions to populate the xorg.conf.d directory with various quirks, yet still have user-specific configuration in the good old xorg.conf.

To better support snippet-based xorg.conf, a new tag has been introduced: AutoServerLayout. Traditionally, any input device needs to be referenced from the ServerLayout section to become active. With AutoServerLayout, an input device may be present in any layout. Hence, your input configuration may look something like this:


Section "InputDevice"
Identifier "touchpad"
Driver "synaptics"
Option "AutoServerLayout" "on"
EndSection


Regardless of which layout is started, the touchpad will always be part of the input device list.

InputClass matching


With the hotplugging support, much of the configuration wandered into the HAL fdi files. This was never the best solution but at that time the only available one. With udev, the fdi files went away and instead of requiring users to port HAL-specific configuration to udev-specific configuration, Dan has stepped in and wrote a set of patches that allow similar functionality to the fdi configuration as part of the xorg.conf (or xorg.conf.d).


InputClasses are similar to InputDevices but can apply to multiple devices (and multiple classes may apply to one device). They work on match rules, with the following matches being available:

MatchProduct, MatchVendor, MatchDevicePath, MatchIsKeyboard, MatchIsPointer, MatchIsJoystick, MatchIsTablet, MatchIsTouchpad, MatchIsTouchscreen

Their meaning is what they describe, with the first three being substring matches, the others being binary matches. An input class is assigned to a device if all match rules apply. As an example, the following snippet would assign the synaptics driver to all touchpads:


Section "InputClass"
Identifier "synaptics-catchall"
Driver "synaptics"
MatchIsTouchpad "on"
EndSection


Or, the catchall evdev rule that applies to every device.

Section "InputClass"
Identifier "evdev-catchall"
Driver "evdev"
EndSection


Or, a more complicated example to set a specific option:

Section "InputClass"
Identifier "vendor-quirk"
MatchVendor "SomeVendor"
MatchDevicePath "/dev/magicdevice"
MatchIsTouchpad "on"
Option "Quirk" "on"
EndSection


Input classes are cumulative and only apply if a given option hasn't been set yet. Hence, the first Driver match will apply and the evdev catchall needs to be the last file matched. This is a bit odd at first, but it again guarantees that the user-defined xorg.conf takes precedence.

We may see some more match conditions before 1.8 is released, but for now the ones above seem to suffice for the general cases.

Monday, December 28, 2009

On commit messages

In the last few weeks, I've had a surprising number of discussions about commit messages. Many of them were with developers new to a project, trying to get them started. So here's a list of things you should do when committing, and why you should do it. Hint: the linux kernel mailing list gets it right, go there to learn.

Any software project is a collaborative project. It has at least two developers, the original developer and the original developer a few weeks or months later when the train of thought has long left the station. This later self needs to reestablish the context of a particular piece of code each time a new bug occurs or a new feature needs to be implemented.

Re-establishing the context of a piece of code is wasteful. We can't avoid it completely, so our efforts should go to reducing it to as small as possible. Commit messages can do exactly that and as a result, a commit message shows whether a developer is a good collaborator.

A good commit message should answer three questions about a patch:

  • Why is it necessary? It may fix a bug, it may add a feature, it may improve performance, reliabilty, stability, or just be a change for the sake of correctness.

  • How does it address the issue? For short obvious patches this part can be omitted, but it should be a high level description of what the approach was.

  • What effects does the patch have? (In addition to the obvious ones, this may include benchmarks, side effects, etc.)



These three questions establish the context for the actual code changes, put reviewers and others into the frame of mind to look at the diff and check if the approach chosen was correct. A good commit message also helps maintainers to decide if a given patch is suitable for stable branches or inclusion in a distribution.

A patch without these questions answered is mostly useless. The burden for such a patch is on each and every reviewer to find out what the patch does and how it fixes a given issue. Given a large number of reviewers and a sufficiently complex patch, this means many man-hours get wasted just because the original developer did not write a good commit message. Worse, if the maintainers of the project enforce SCM discipline, they will reject the patch and the developer needs to spend time again to rewrite the patch, reviewers spend time reviewing it again, etc. The time wasted quickly multiplies and given that a commit message only takes a few minutes to write, it is simply not economically viable to omit them or do them badly.

Consider this is a hint for proprietary software companies too - not having decent SCM discipline costs money!


How to do it better


There's no strict definition of the ideal commit message, but some general rules have emerged.
A commit should contain exactly one logical change. A logical change includes adding a new feature, fixing a specific bug, etc. If it's not possible to describe the high level change in a few words, it is most likely too complex for a single commit. The diff itself should be as concise as reasonably possibly and it's almost always better to err on the side of too many patches than too few. As a rule of thumb, given only the commit message, another developer should be able to implement the same patch in a reasonable amount of time.

If you're using git, get familiar with "git add -p" (or -i) to split up changes into logical commits.

The git commit format


If you're submitting patches for git, the format is mostly standardised. A short one-line summary of the change (the maximum length of the line differs between projects, it's usually somewhere between 50 and 78 characters). This is the line that'll be seen most often, make it count. Many git tools are in one way or another optimised for this format. After that one-line summary, an empty line, then multiple paragraphs explaining the patch in detail (if needed). Don't describe the code, describe the intent and the approach. And keep the log in a present tense.

Learn to love the log


I have used CVS (and SVN to a lesser extent) in the past and log was a tool that was hardly ever used. Mostly because it was pretty useless, both the tool and the information available. These days I look at git logs more often than at code. The git log tool is vastly superior to CVS log and the commit discipline in the projects I'm working on now is a lot better. I grep git logs more often than code files and I use git blame all the time to figure out why a particular piece of code looks the way it does. It's certainly saving me a lot of time and effort. It's come to the point where the most annoying X server bugs are the ones where the git history stops at the original import from XFree86. If you're not using your SCM's log tool yet, I recommend to get more familiar with it.

How not to do it


There's a bunch of common sins that are committed (yay, a pun!) regularly.


  • SCM is not a backup system! My personal pet hate. Developers who use it as such tend to do end-of-day commits, checking in everything at the end of the day. The result is useless, a random diff across the code with changes that are impossible to understand by anyone including the original author once a few months have passed. (On this note: universities, please stop teaching this crap).

  • Per-file commit. More often than not a logical change affects more than one file and it should not be split up into two commits.

  • Lazy commit messages, any commit labelled as "misc fixes and cleanups" or similar. I've seen my fair share of those on non-FOSS projects and they always come back to bite you. Impossible to find when a bug was introduced, hard to bisect and makes it harder for anyone else to keep track of what's happening in the project.

  • Two changes in one patch. Something like "Fixed bug 2345 and renamed all foo to bar". Unless bug 2345 required the renaming, fixes whould be split it up into multiple patches. Others may have to take one of those bug fixes and apply it to a stable branch but not the other one. Picking bad patches apart into useful chunks is one of the most time-consuming and frustrating things I've done since it doesn't actually add any value to the project.

  • Whitespace changes together with code changes. Needle in a haystack is a fun game, but not when you're looking at patches. It's a great way to introduce bugs, though because almost no-one will spot the bug hidden in hundreds of lines that got reindented for fun and profit.

  • The ever-so-lovely code drops. Patches with hundreds of lines of code to dump a new feature into the code while at the same time rewriting half the existing infrastructure to support this feature. As a result, those hundreds of lines of code need to be reviewed every time a bug is discovered that is somehow related to that area of code.
    It's easier and less time consuming to first rework the infrastructure one piece at a time, then plug the new feature on top. As a side-effect, if a project relies on code dumps too often it's discouraging outside developers. Would you like to contribute to a project where the time spent filtering the signal from the noise outweighs the actual contribution to the code?

  • Unrelated whitespace changes in patches. A reviewer needs to get the big picture of a patch into their brains. Whitespace-only hunks just confuse, a reviewer has to look extra hard to check if there's a real change or whether it can be ignored. That's not so bad for empty lines added or removed,it's really bad for indentation changes.



There's plenty of excuses for the above, with the favourite one being "but it works!". It may work, but code is not a static thing. In a few weeks time, that code may have moved, been rewritten, may be called in a different manner or may have a bug in it. At the same time, the original developer may have moved on and no-one knows why the code is that way. In the worst case, everyone is afraid of touching it because nobody knows how it actually works.

Another common excuse is the "but I'm the only one working on it". Not true, any software project is a collaborative project (see above). Assuming that there's no-one else is simply short-sighted. In FOSS projects specifically we rely on outside contributors, be it testers, developers, triagers, users, etc. The harder it becomes for them to join, the more likely the project will fail.

Another, less common excuse these days is that the SCM used is too slow. Distributed SCMs avoid this issue, saving time and by inference money.

Thursday, December 24, 2009

Bisecting your favourite bug.

Ran into a new bug? Wasn't there with the last version? Want a developer to fix it? Too easy, just bisect it. And here's how:

First of all, we assume you've been running whatever your distribution ships. Find out that version and find the upstream repository. Now clone that repository and check out the matching version. For the example below, let's assume 1.2 is fine and 1.3 is broken.


$> git clone git://host/path/to/project
$> cd project
$> git tag
# find tag name for the broken version
$> git checkout project-1.3 # the broken version
$> ./configure $CONFIGUREFLAGS
$> make && make install
# test


You can get the configure flags from your distribution's build system. e.g. Fedora's koji. Look up the build of the version, go into the build.log and copy the configure flags from there. After that, the project will be installed in the same location, with the same flags as the rpm/deb/whatever file.
Verify it's still broken with this version, if not it might be distribution-specific patches. If it's still broken, check out the working version and verify that one too.


$> git checkout project-1.2 # the working version
$> make && make install
# test


So, you've just verified that vanilla 1.2 works and 1.3 doesn't? Great, off to bisecting.


$> git bisect start
$> git bisect good project-1.2
$> git bisect bad project-1.3


git now gives you a version in between those two, simply build and install it, test it and depending on whether it works or not, run "git bisect good" or "git bisect bad". After a number of test runs, git will tell you which commit introduced the bug. And you're done, send this commit info to the developers and they'll have a much easier time fixing the bug.

Now, of course nothing is as easy as it seems so you may see versions that you can't build (git bisect skip) or you'll run into dependency issues between versions so you can't bisect further. I've had some reasonable success with the process above and the smaller the range of commits you can provide to the developers the better.

You can use the same process for distribution-specific patches too. After checking out a a working version, just apply all patches from that distro in-order and then bisect between the working version and HEAD. Works like a treat.

Friday, December 11, 2009

The [Xx]([Ff](ree)?[86]|[\.]?[Oo]rg) glossary

Hello, and welcome to this week's episode of "confusing wordcronyms". This time we'll have a look at letter combinations starting with X, ending in org or 86, and referring to a popular windowing system. Hint: the "X Window System" is an umbrella term for a windowing system based on the X protocol.

Here we go:

X

preferred shorthand for lazy typers or people with most of their keyboard missing. Refers to some incarnation of the X Window System. Is also a symlink to the binary of X servers.

X.Org

Official name of the X.Org project. "The X.Org project provides an open source implementation of the X Window System. [...] The X.Org Foundation is the educational non-profit corporation whose Board serves this effort, and whose Members lead this work." [source]

x.org

URL used by the X.Org project. Sometimes used to refer to X.Org by those with a broken Shift key.


XFree86

"The XFree86 Project, Inc is a global volunteer organization which produces XFree86®, the freely redistributable open-source implementation of the X Window System continuously since 1992." [source] Due to some not-so-exciting political issues, the code produced by XFree86 was forked and most developers shifted to X.Org instead. Today's code is the continuation of what used to be XFree86 code, though XFree86 itself is mostly dead now.


Xorg

The binary name of the X.Org X server implementation.


xfree86

The DDX name for the commonly used X server. A DDX is the device-dependent part of the X server and together with the device-independent bits (DIX) and some other parts forms your binary. The xfree86 DDX is what loads your video drivers and input drivers (amongst other things). Other well-known DDXs are kdrive, Xnest and Xdmx. All patches you see with xfree86 prefixes or pathnames patch this particular DDX.


xf86

Shorthand for drivers that can be loaded by the xfree86 DDX. For example, xf86-input-evdev, xf86-video-ati, etc.


xorg

Firstname of the xorg.conf server configuration file. Lovingly spelled lowercase because we can.




If you're reading this, chances are that you are running Xorg, the xfree86 DDX from the X.Org X server implementation with various xf86-something drivers. How can that possibly be confusing? Pass the mustard, thanks.