Canonical Voices

What Subcritical talks about

Eric Williams

Notes

You can use LVM for /boot, /, and any other filesystem. GRUB in lucid and later supports booting from LVM.

You don't need to partition disks to use them with LVM. In fact, this is usually just annoying and not useful. Use pvcreate directly on the block devices.

Directly using the block devices also overcomes the MBR format's limit of 2.1 terabytes. LVM supports PVs on block devices up to who knows how big.

  • For 32-bit CPUs on 2.6 kernels, the maximum LV size is 16TB. That'll do you.

  • For 64-bit CPUs on 2.6 kernels, the maximum LV size is 8EB.

See also:

TLDP: http://tldp.org/HOWTO/LVM-HOWTO/lvm2faq.html#AEN407

Now, let's start playing around with LVM.

Setup a KVM with some extra block devices to use as an LVM sandbox

I've installed 64-bit Precise Server into a VM called precise-x64. I've added the block devices as SCSI devices

    #!/bin/bash

    VM="precise-x64"

    for i in {a..f}; do  
      sudo qemu-img create -f qcow2 /var/lib/libvirt/images/${VM}_vd${i}.img 4G
      sudo virsh attach-disk ${VM}  /var/lib/libvirt/images/${VM}_vd${i}.img vd${i} --type disk --subdriver qcow2 --persistent
    done

    sudo virsh start ${VM}
    #EOF
  • Setting up LVM inside the VM

    $ sudo vgcreate vg_lvm_test /dev/vd{a..f}
      No physical volume label read from /dev/vda
      Physical volume "/dev/vda" successfully created
      [...]
      Volume group "vg_lvm_test" successfully created
    
    $ sudo lvcreate -n "lv_lvm_test" -L 5G vg_lvm_test
      Logical volume "lv_lvm_test" created
    

The Basics

  • pvs: show physical volumes:

    $ sudo pvs
      PV         VG          Fmt  Attr PSize PFree
      /dev/vda   vg_lvm_test lvm2 a-   4.00g 4.00g
      /dev/vdb   vg_lvm_test lvm2 a-   4.00g 4.00g
      /dev/vdc   vg_lvm_test lvm2 a-   4.00g 4.00g
      /dev/vdd   vg_lvm_test lvm2 a-   4.00g 4.00g
      /dev/vde   vg_lvm_test lvm2 a-   4.00g 4.00g
      /dev/vdf   vg_lvm_test lvm2 a-   4.00g 4.00g
    
  • vgs: volume groups

    $ sudo vgs
      VG          #PV #LV #SN Attr   VSize  VFree 
      vg_lvm_test   6   1   0 wz--n- 23.98g 18.98g
    

PV: Number of physical volumes in this group

SN: Snapshots

Attributes: See man vgs for the attributes columns

Notice "VSize" and "VFree". It's always a nice feeling to have a bit of free space in your volume groups.

  • lvs: show logical volumes

    $ sudo lvs
      LV          VG          Attr   LSize Origin Snap%  Move Log Copy%  Convert
      lv_lvm_test vg_lvm_test -wi-a- 5.00g
    

Filesystem resizing

Resizing filesystems on LVM is almost trivial.

Resize the LV into your VG's free space (add free space with vgextend if there is none in the VG).

    $ sudo vgs
      VG              #PV #LV #SN Attr   VSize  VFree
      vg_lvm_test       4   1   0 wz--n- 15.98g 5.98g

    $ sudo mkfs.ext4 /dev/vg_lvm_test/lv_lvm_test
    ...
    $ sudo mount /dev/vg_lvm_test/lv_lvm_test /mnt/

    Filesystem                           Size  Used Avail Use% Mounted on
    /dev/sda1                            7.0G  1.1G  5.6G  17% /
    udev                                 490M  4.0K  490M   1% /dev
    tmpfs                                200M  304K  199M   1% /run
    none                                 5.0M     0  5.0M   0% /run/lock
    none                                 498M     0  498M   0% /run/shm
    /dev/mapper/vg_lvm_test-lv_lvm_test  5.0G  204M  4.6G   5% /mnt

OK, we've got a 5.0G filesystem mounted at /mnt. Let's give him a couple more megabytes.

    $ sudo lvextend vg_lvm_test/lv_lvm_test -L +2G
      Extending 2 mirror images.
      Extending logical volume lv_lvm_test to 7.00 GiB
      Logical volume lv_lvm_test successfully resized

    $ sudo resize2fs /dev/vg_lvm_test/lv_lvm_test

    $ sudo resize2fs /dev/vg_lvm_test/lv_lvm_test
    resize2fs 1.42 (29-Nov-2011)
    Filesystem at /dev/vg_lvm_test/lv_lvm_test is mounted on /mnt; on-line
    resizing required
    old_desc_blocks = 1, new_desc_blocks = 1
    Performing an on-line resize of /dev/vg_lvm_test/lv_lvm_test to 1835008 (4k)
    blocks.

    $ df -h
    Filesystem                           Size  Used Avail Use% Mounted on
    /dev/sda1                            7.0G  1.1G  5.6G  17% /
    udev                                 490M  4.0K  490M   1% /dev
    tmpfs                                200M  304K  199M   1% /run
    none                                 5.0M     0  5.0M   0% /run/lock
    none                                 498M     0  498M   0% /run/shm
    /dev/mapper/vg_lvm_test-lv_lvm_test  7.0G  205M  6.5G   4% /mnt

You can do this with mounted filesystems, even the root filesystem.

Mirroring

We're going to mirror the logical volume that we just created, lv_lvm_test, using the lvconvert command:

    $ sudo lvconvert -m1 vg_lvm_test/lv_lvm_test
      vg_lvm_test/lv_lvm_test: Converted: 0.0%
      vg_lvm_test/lv_lvm_test: Converted: 4.9%

You can ^C this process and it will continue in the background. Check its progress with the "lvs" command.

    $ sudo lvs
      LV          VG          Attr   LSize Origin Snap%  Move Log Copy%  Convert
      lv_lvm_test vg_lvm_test mwi-a- 5.00g lv_lvm_test_mlog       16.02

The mirrored volume has 3 components: 2 mirror copies and the disklog. The disklog tracks changes and keeps the volumes in sync.

You can see the different components, and their physical locations, using the pvs command.

    $ sudo pvs -o lv_name,pv_name
      LV                     PV        
      [lv_lvm_test_mimage_0] /dev/vda  
      [lv_lvm_test_mimage_0] /dev/vdb  
      [lv_lvm_test_mlog]     /dev/vdb  
                             /dev/vdb  
      [lv_lvm_test_mimage_1] /dev/vdc  
      [lv_lvm_test_mimage_1] /dev/vdd  
                             /dev/vdd  
                             /dev/vde  
                             /dev/vdf

Note that the mirrored segments are named $LVNAME_mimage_0 and $LVNAME_mimage_1. The logical volume is 5GB, which is bigger than the physical volumes, which are all 4GB. The 5GB segments are split across a couple of physical volumes each. LVM will try to "do the right thing" and prevent mimage segments from occupying the same physical devices.

There's a third part, the disklog, named $LVNAME_mlog. In this example, part of mimage_0 and mlog are on the same physical volume, vdb.

Corelog

When you create a mirror, you can also use "corelog" instead of disklog. This keeps the mirror log in RAM instead of on a disk. This way, you don't need to have a disklog segment.

The downside is that the mirror will have to be synchronized at every boot.

    $ sudo pvs -o +lv_name
    [sudo] password for eric: 
      PV         VG          Fmt  Attr PSize PFree LV                    
      /dev/vda   vg_lvm_test lvm2 a-   4.00g    0  [lv_lvm_test_mimage_0]
      /dev/vdb   vg_lvm_test lvm2 a-   4.00g 2.99g [lv_lvm_test_mimage_0]
      /dev/vdb   vg_lvm_test lvm2 a-   4.00g 2.99g [lv_lvm_test_mlog]    
      /dev/vdb   vg_lvm_test lvm2 a-   4.00g 2.99g                       
      /dev/vdc   vg_lvm_test lvm2 a-   4.00g    0  [lv_lvm_test_mimage_1]
      /dev/vdd   vg_lvm_test lvm2 a-   4.00g 2.99g [lv_lvm_test_mimage_1]
      /dev/vdd   vg_lvm_test lvm2 a-   4.00g 2.99g                       
      /dev/vde   vg_lvm_test lvm2 a-   4.00g 4.00g                       
      /dev/vdf   vg_lvm_test lvm2 a-   4.00g 4.00g

Since /dev/vde and /dev/vdf don't have any LV segments on them, we'll take them out of vg_lvm_test with the vgreduce command, and put them into a new volume group, vg_corelog_test.

    $ sudo vgreduce vg_lvm_test /dev/vde /dev/vdf
      Removed "/dev/vde" from volume group "vg_lvm_test"
      Removed "/dev/vdf" from volume group "vg_lvm_test"

    $ sudo vgcreate vg_corelog_test /dev/vde
      Volume group "vg_corelog_test" successfully created

Create the LV:

    $ sudo lvcreate -n lv_corelog -l 100%FREE vg_corelog_test
      Logical volume "lv_corelog" created

    $ sudo vgs
      VG              #PV #LV #SN Attr   VSize  VFree
      vg_corelog_test   1   1   0 wz--n-  4.00g    0
      vg_lvm_test       4   1   0 wz--n- 15.98g 5.98g

Now we double the amount of space in the VG by adding another PV, /dev/vdf:

    $ sudo vgextend vg_corelog_test /dev/vdf
      Volume group "vg_corelog_test" successfully extended

    $ sudo vgs
      VG              #PV #LV #SN Attr   VSize  VFree
      vg_corelog_test   2   1   0 wz--n-  7.99g 4.00g
      vg_lvm_test       4   1   0 wz--n- 15.98g 5.98g

We convert the volume to be mirrored:

    $ sudo lvconvert -m1 vg_corelog_test/lv_corelog
      Insufficient suitable allocatable extents for logical volume : 1023 more required
      Unable to allocate extents for mirror(s).

We don't have enough room for the mirror in our volume group, since it requires a disklog by default.

    $ sudo lvconvert -m1 vg_corelog_test/lv_corelog --corelog
      vg_corelog_test/lv_corelog: Converted: 0.0%
      vg_corelog_test/lv_corelog: Converted: 7.2%
      vg_corelog_test/lv_corelog: Converted: 14.3%
      vg_corelog_test/lv_corelog: Converted: 21.4%

Moving PVs around with pvmove

Let's make room by getting rid of our corelog thing.

    $ sudo vgremove vg_corelog_test
    Do you really want to remove volume group "vg_corelog_test" containing 1
    logical volumes? [y/n]: y
    Do you really want to remove active logical volume lv_corelog? [y/n]: y
      Logical volume "lv_corelog" successfully removed
      Volume group "vg_corelog_test" successfully removed

Now we'll add the old PVs back into the volume group, vg_lvm_test.

    $ sudo vgextend vg_lvm_test /dev/vde /dev/vdf
    $ sudo pvs
      PV         VG          Fmt  Attr PSize PFree   
      /dev/vda   vg_lvm_test lvm2 a-   4.00g       0 
      /dev/vdb   vg_lvm_test lvm2 a-   4.00g 1012.00m
      /dev/vdc   vg_lvm_test lvm2 a-   4.00g       0 
      /dev/vdd   vg_lvm_test lvm2 a-   4.00g 1016.00m
      /dev/vde   vg_lvm_test lvm2 a-   4.00g    4.00g
      /dev/vdf   vg_lvm_test lvm2 a-   4.00g    4.00g

Let's say that we've got the sick feeling that /dev/vdb is about to die on us. Let's move it over to the much newer /dev/vde.

    $ sudo pvmove /dev/vdb /dev/vde
      Skipping mirror LV lv_lvm_test
      Skipping mirror log LV lv_lvm_test_mlog
      Skipping mirror image LV lv_lvm_test_mimage_0
      Skipping mirror image LV lv_lvm_test_mimage_1
      All data on source PV skipped. It contains locked, hidden or non-top level
      LVs only.
      No data to move for vg_lvm_test

D'oh! It's our mirror. We'll have to break it first.

    $ sudo lvconvert -m0 vg_lvm_test/lv_lvm_test

    $ sudo pvmove /dev/vdb /dev/vde
      /dev/vdb: Moved: 0.0%

You can ^C this. You can check back on the move at any time by just running pvmove:

    $ sudo pvmove
      /dev/vdb: Moved: 9.5%
      /dev/vdb: Moved: 18.7%

pvmove works by temporarily mirroring the source and target PVs. Check the output of dmsetup ls --tree:

    $ sudo dmsetup ls --tree
    vg_lvm_test-lv_lvm_test (252:0)
     ??vg_lvm_test-pvmove0 (252:1)
     ?  ?? (253:64)
     ?  ?? (253:16)
     ?? (253:0)

Even if the machine crashes in the middle of a pvmove, it won't affect it. It will just pick up where it left off when the machine gets rebooted.

pvmove works on online devices and mounted filesystems, including the root filesystem. Cool!

Read more
Eric Williams

Me and my poor old Desire

Is it me, or did google just obsolete my 1-year-old HTC Desire?

Google let us know today that they're finally releasing Chrome for the Android platform, albeit only for Android 4.0:

Today, we're introducing Chrome for Android Beta, which brings many of the things you’ve come to love about Chrome to your Android 4.0 Ice Cream Sandwich phone or tablet.

Infamous Google fanboy Thom Holwerda claims that Chrome will replace the default Android browser, Browser.

All well and good, considering the utter crappiness of the current default browser. But

PC Magazine lists the devices that will be getting Ice Cream Sandwich upgrades:

Good news, HTC Sensation owners – you're first on the list for an Ice Cream Sandwich upgrade. But HTC also added more phones to its ICS upgrade roadmap. Ice Cream Sandwich upgrades will be coming later this year to the HTC Rezound, HTC Vivid, HTC Amaze 4G, HTC EVO 3D, HTC EVO Design 4G, HTC Incredible S, HTC Desire S and HTC Desire HD," the company added. "Stay tuned for more updates on Ice Cream Sandwich releases in the coming weeks."

Notice that the HTC Desire is not on that list. In the year that I've been using this Android phone, I've been able to upgrade from Android 2.2 to 2.3 by means of a Jailbreak. I've never updated it otherwise, nor been prompted to do so by the operating system. In that time, Android has moved to 3.0 and then to 4.0 now with Ice Cream Sandwich.

In contrast, my 4 year old iPod Touch has been updated all the way to iOS 5.something. Most of the really good features aren't available, sadly. Apple decided not to enable multitasking on hardware that old. Also, over-the-wire syncing is not available. Nevertheless, I've got the most recent browser and (I assume) all relevant security updates.

The HTC Desire will never move forward, I guess. It will always be stuck in 2010. So much for "open".

Read more
Eric Williams

Our goal here is the following:

  • have BBB running on Ubuntu

  • Use Launchpad SSO to control access

  • Organize multiple web meetings easily

We're going to be using Drupal, Apache, and Big Blue Button.

Installing the server

Big Blue Button instructions are pretty straightforward. If you're going to be using the Drupal integration bit (see below) stick with 0.7.

If you're running in an LXC instance

First, setup an lxc instance on your local machine:

sudo lxc-create -t ubuntu -n bbb -f /etc/lxc/lxc-veth.conf -- -r lucid

Chroot into /var/lib/lxc/ and setup your environment, adding a sudo user, etc. Then, startup the instance.

After the machine is up and running, add the -updates repo to /etc/apt/sources.list.

sudo lxc-start -n bbb

Login to the instance and update it. Due to a bug in lxc's stuff, you'll need to umount /usr/lib/init/fstab before it will run.

You probably also want to edit /var/lib/lxc/bbb/config and set a static hardware address. Otherwise, your IP address will change between boots and break the BBB server's configuration.

If you're running in an Amazon cloud

After the installation finishes, you'll need to set the BBB configuration to use external IP of the instance.

bbb-conf --setip ec2-107-21-198-130.compute-1.amazonaws.com

Then add the hostname to /etc/hosts with the private IP address.

For all machines

Now, just follow the steps in:

http://code.google.com/p/bigbluebutton/wiki/InstallationUbuntu

Once you're done, you should be able to login to your bbb server and test it.

Using with Drupal

For some reason, the BBB developers decided that apache wasn't good enough for them, and went with nginx. Drupal will probably work with nginx, but it's not trivial to setup. And that's what we want: Trivial.

Change BBB's listening port to 81:

sudo bbb-conf --setip bigbluebutton.mydomain.org:81
sudo bbb-conf --clean

Check now to make sure that /etc/nginx/sites-available/bigbluebutton has been updated with the new port number.

Change nginx's ports to 81 in /etc/nginx/sites-available/default

Restart nginx, and test http://bbb.local:81/ . It should give you the full big blue button experience.

Now let's install Drupal6:

sudo apt-get install drupal6

In your browser, go to http://bbb.local/drupal6/install.php and make it so.

Grab the BBB Drupal module:

cd /usr/share/drupal6/modules/
sudo wget http://ftp.drupal.org/files/projects/bbb-6.x-1.x-dev.tar.gz
sudo tar zxvf bbb-6.x-1.x-dev.tar.gz
sudo rm bbb-6.x-1.x-dev.tar.gz

Go to Administration -> Site Building -> Modules, and enable the BBB module

Once enabled, go to Site Configuration -> Big Blue Button meetings and configure the API connection.

Base URL: http://bbb.local:81/bigbluebutton/api/

Don't forget the :81 (like I always do).

Security salt:  value beans.dynamicConferenceService.securitySalt from

/var/lib/tomcat6/webapps/bigbluebutton/WEB-INF/classes/bigbluebutton.properties

Using with Launchpad OpenID and Drupal (Optional)

First off, grab the Launchpad OpenID extensions from here:

https://code.launchpad.net/~canonical-isd-hackers/drupal-launchpad/6.x-trunk
bzr branch lp:drupal-launchpad/6.x
mv 6.x openid-launchpad  # this needs to come after "openid", due to
               # hackage
tar fcz openid-launchpad.tar.gz openid-launchpad

Then unpack that so that you have /usr/share/drupal6/modules/openid-launchpad.

Go into Site Building -> Modules, and enable "Launchpad OpenID".

Now, go into Site Building -> Blocks, and remove the usual login screen, and add the OpenID launchpad login button somewhere where the users can find it.

Set authorized users' permissions so that they can attend meetings, create content.

If everything is working at this point, you might want to upgrade your BBB instance to 0.8. There are some improvements to the meeting layout, which is especially good when you have a lot of people's video windows to move around.

The instructions for upgrade are here:

http://code.google.com/p/bigbluebutton/wiki/08InstallationUbuntu#Upgrading_from_BigBlueButton_0.71a

Since we also have Drupal and Apache running, I would advise stopping apache before starting, and telling BBB to overwrite the existing nginx configuration files.

After the upgrade, just run the bbb-conf command again to reset the port to 81:

sudo bbb-conf --setip bigbluebutton.mydomain.org:81

Then restart apache2. It's fairly easy and has worked for me pretty well.

Here are some scripts that may lighten the load a little bit:

  1. Install BBB
  2. Upgrade from 0.7a to 0.8beta
  3. Upgrade Ruby

Read more
Eric Williams

Windows 7

I finally got around to installing Windows 7 on bare metal this weekend. I've been roped into installing Windows Server occasionally, but always in a VM, and only for testing Linux interoperability with packages like Centrify and Likewise.

It's the first time I've installed Windows on a machine in 6 years. The last time, it was to play Doom 3 and Half-Life 2. The old PowerBook G4 was not up to those mighty titles, so I pressed my (then-)meaty P4 machine into service.

I've always heard good things about Windows 7, even from Mac fanboys. It has a reputation for being light, fast, and pretty.

The Good

Installation wasn't too awkward. I remember Windows XP being annoying and fidgety, especially when installing alongside existing operating systems. Windows 7's installation asks few questions and then goes about its business. It also managed to not completely blow away my Ubuntu installation, being satisfied with destroying my MBR and rendering my other OS's inaccessible.

The Super+tab switching, which shows the windows stacked up and cycles through them, is pretty slick. I found myself using that more than anything to get around. It's on par with Expose as a productivity enhancer, and Ubuntu's Unity could learn a thing or two from that.

The OS itself is still fairly snappy, even with all the new added bling. Not to say that it's faster than Ubuntu or Mac OS X, but it competes.

The Bad

Having used Mac and Linux exclusively for years, the first thing that hit me is: Windows font-handling is still shit. Apple products are known for their excellent typography, so it's no surprise that it whips Windows on that front. But even Ubuntu beats the shit out of Windows when it comes to font rendering. The choice of fonts and the anti-aliasing tech is so bad, I get a headache trying to read it. I tried monkeying around with the ClearType settings, but was still getting ghosting and blurriness.

I installed Windows 7 on Dell OptiPlex 380 small form-factor machine, which is fairly run-of-the-mill hardware. Windows 7's support for Sandy Bridge is admirable, but the Network driver wasn't there. I had to boot into Ubuntu and download the driver pack from Dell.

I also had trouble burning DVDs. I was able to burn two easily and successfully, but after that, I just got coasters. No big deal, seeing as I have spindles and spindles of blank DVDs that I never thought I'd use anyway, but this is still an area where I figured Windows would shine.

The Ugly

The following are things that I consider to be matters of personal taste. I've always found NT to be a good operating system, with a technologically advanced kernel and a lot of brains architecting it. But I'll be upfront about my dislike of Windows as a user environment.

Windows Aero looks outdated to me. I don't like the gigantic chrome surrounding all the windows, nor the transparency effects. The clicky-bloopy sound effects get old fast. There's a sound hit for virtually every action. Clicking, showing menus, closing windows, logging in, notification bubbles. And when you're listening to music on a nice pair of speakers, you really don't need a 25-watt orchestra hit that tells you that your antivirus just updated itself.

The main thing I don't like about the Windows interface is that almost everything seems to be excessive. For example, the progress bars have a little lens-flare effect that sweeps across every few seconds. I have no idea what it means. Also, the window chrome blurs whatever's behind it, simulating translucency. But the blur is sever enough that you can't really tell what's behind it, only that something is behind it. They should have just dropped that.

Conclusion

Screw you, Windows. I'll continue to order my PC hardware explicitly without you, and stick to modern operating systems.

Read more

Occasionally, you'll need to find stuff on a Linux filesystem that seems to have disappeared. For example, if you're seeing big differences between the output of df and du, and you can't figure out where your disk space went.

You'll eventually need to look under any mounted filesystems, such as /var or /home in many cases, to make sure that no files have been hidden underneat their mount points. Normally, you'll be told to unmount those filesystems.

There's an easier way to do this, though, using bind mounts.

sudo mkdir /root_bind
sudo mount -o bind / /root_bind

cd /root_bind
sudo du -h --max-depth=1 /root_bind

Compare this with the output of "du -h --max-depth=1 /" and see if there's anything that jumps out at you. Oh, and don't forget to unmount /root_bind.

Read more
Eric Williams

Remote Highlight Notifications with IRSSI

Running IRSSI remotely has many advantages. You can just login and logout of your screen session without having to miss any of the constant stream of nonsense that your IRC channels are filled with, for example. You can also pick up an SSH client and continue your IRC session no matter where you are.

One thing that isn't so great about running your sessions remotely is notifications. If you're running IRSSI locally in an xterm, there are several solutions to get libnotify popups to show up whenever a highlighted word is show. I use a variant of the hilightwin.pl script.

Running IRSSI remotely, I've changed the script a little bit. Instead of popping up a libnotify bubble, it pings a local XMLRPC service with the highlight information:

$server_url = 'http://qnap.local:8000/RPC2';
$server = Frontier::Client->new(url => $server_url);
$result = $server->call('add_message', (@args));

The XMLRPC service keeps a list in memory of notifications, and makes them available to remote method calls, like num_messages and next_message.

On the local machine, I run a python XMLRPC client. It polls the XMLRPC service, and uses the libnotify python bindings to pop up a message whenever there's a highlight.

This is unbelievably insecure, of course. There should probably be some sort of authentication going on, yes, but I run it on an internal network, accessible via VPN, so I have my notifications without too much worry.

So now I leave my IRC session running in a screen on my little ARM server, which I can login to remotely without sacrificing my notify bubbles.

Some stuff I'm planning on adding:

  • A systray- or indicator-style applet that shows the last /x/ number of highlights

  • Notifications from applications other than IRSSI

  • Idle detection on the client, so I can run multiple notify clients without worrying about them stepping on each other's RPC traffic

Read more
Eric Williams

Fixing that Broken Xterm under Compiz and Unity

First off, why Xterm? It's lightweight, it's easy, and it doesn't suffer from trackpad scroll-madness like GNOME Terminal. Whenever I'm using tmux under GNOME Terminal on my laptop, inadvertent scroll-wheel events often cause me to send the wrong commands or write nonsense into IRC.

Unfortunately, Compiz and Xterm do not play well together. Due to how Compiz calculates its textures, Xterm displays tend to get garbled.

Having had my fill of gnome-terminal, I finally got around to figuring out the workaround for this. Just put the following in .Xdefaults:

! Workaround for compiz issues
XTerm*borderWidth: 0

Then xrdb ~/.Xdefaults && xterm, and you're back in old-school business.

Read more
Eric Williams

Fixing that Broken Xterm under Compiz and Unity

First off, why Xterm? It's lightweight, it's easy, and it doesn't suffer from trackpad scroll-madness like GNOME Terminal. Whenever I'm using tmux under GNOME Terminal on my laptop, inadvertent scroll-wheel events often cause me to send the wrong commands or write nonsense into IRC.

Unfortunately, Compiz and Xterm do not play well together. Due to how Compiz calculates its textures, Xterm displays tend to get garbled.

Having had my fill of gnome-terminal, I finally got around to figuring out the workaround for this. Just put the following in .Xdefaults:

! Workaround for compiz issues
XTerm*borderWidth: 0

Then xrdb ~/.Xdefaults && xterm, and you're back in old-school business.

Read more

Launchd in Ubuntu

In the various flavors of UNIX, you usually have an init or init-like process which wrangles all the sundry system services. Things like your mail server, your ftp server, etc. all have to be started by something.

In Ubuntu, we use Upstart since Lucid. It's a modern, event-based init daemon. Red Hat Enterprise Linux 5 uses the fine old SysVInit system. In RHEL 6, you also have Upstart, but it's being run in a SysVInit-compatibility mode. RHEL's cousin, Fedora, uses systemd.

Under Mac OS X Tiger and later, there's launchd. This not only ditches replaces init, but also cron and a couple of other traditional UNIX facilities.

According to The Book of Knowledge

The Ubuntu Linux distribution considered using launchd in 2006. However, launchd was rejected as an option because it was released under the Apple Public Source License – which at the time was described as an "inescapable licence problem".

In August 2006, Apple relicensed launchd under the Apache License, Version 2.0 in an effort to make adoption by other open source developers easier.

I'm not so convinced that licensing was the main reason that launchd was passed over. I wasn't around Ubuntu or Canonical at the time, and I've heard conflicting accounts from various Canonical employees on the matter.

With as much time and effort as we've put into Upstart in the meanwhile, it's turned out to be pretty good solution.

People complain about the upstart configuration file syntax. If you compare it aginast the property list approach, though, it's like writing hot buttered biscuits and bacon.

For comparison, here's a property list for postfix (stolen from Macworld):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>org.postfix.master</string>
        <key>Program</key>
        <string>/usr/libexec/postfix/master</string>
        <key>ProgramArguments</key>
        <array>
                <string>master</string>
        </array>
</dict>
</plist>

Postfix isn't upstartified in Ubuntu (yet), but here's a comparable rsyslog upstart config:

# rsyslog - system logging daemon
#
# rsyslog is an enhanced multi-threaded replacement for the traditional
# syslog daemon, logging messages from applications

description     "system logging daemon"

start on filesystem
stop on runlevel [06]

expect fork
respawn

script
    . /etc/default/rsyslog
    exec rsyslogd $RSYSLOGD_OPTIONS
end script

Launchd might be stable, and it's what all the cool BSD kids are running these days, but it breaks one of the commandments: XML is not to be considered human-writable. It's a data format.

Read more

Launchd in Ubuntu

In the various flavors of UNIX, you usually have an init or init-like process which wrangles all the sundry system services. Things like your mail server, your ftp server, etc. all have to be started by something.

In Ubuntu, we use Upstart since Lucid. It's a modern, event-based init daemon. Red Hat Enterprise Linux 5 uses the fine old SysVInit system. In RHEL 6, you also have Upstart, but it's being run in a SysVInit-compatibility mode. RHEL's cousin, Fedora, uses systemd.

Under Mac OS X Tiger and later, there's launchd. This not only ditches replaces init, but also cron and a couple of other traditional UNIX facilities.

According to The Book of Knowledge

The Ubuntu Linux distribution considered using launchd in 2006. However, launchd was rejected as an option because it was released under the Apple Public Source License – which at the time was described as an "inescapable licence problem".

In August 2006, Apple relicensed launchd under the Apache License, Version 2.0 in an effort to make adoption by other open source developers easier.

I'm not so convinced that licensing was the main reason that launchd was passed over. I wasn't around Ubuntu or Canonical at the time, and I've heard conflicting accounts from various Canonical employees on the matter.

With as much time and effort as we've put into Upstart in the meanwhile, it's turned out to be pretty good solution.

People complain about the upstart configuration file syntax. If you compare it aginast the property list approach, though, it's like writing hot buttered biscuits and bacon.

For comparison, here's a property list for postfix (stolen from Macworld):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>org.postfix.master</string>
        <key>Program</key>
        <string>/usr/libexec/postfix/master</string>
        <key>ProgramArguments</key>
        <array>
                <string>master</string>
        </array>
</dict>
</plist>

Postfix isn't upstartified in Ubuntu (yet), but here's a comparable rsyslog upstart config:

# rsyslog - system logging daemon
#
# rsyslog is an enhanced multi-threaded replacement for the traditional
# syslog daemon, logging messages from applications

description     "system logging daemon"

start on filesystem
stop on runlevel [06]

expect fork
respawn

script
    . /etc/default/rsyslog
    exec rsyslogd $RSYSLOGD_OPTIONS
end script

Launchd might be stable, and it's what all the cool BSD kids are running these days, but it breaks one of the commandments: XML is not to be considered human-writable. It's a data format.

Read more

I should have called this, how to kick sed off my living room couch, and tell that lazy scumbag to go out and get a job and stop drinking all my beer. But that was too long.

TL;DR

You can do just about anything inside two {}'s; the laws of nature no longer apply in there..

Substrings

$ export MYVAR=/usr/bin/eric.rocks

$ unset NULLVAR

$ echo ${MYVAR:1}
usr/bin/eric.rocks

$ echo ${MYVAR:9}
eric.rocks

$ echo ${MYVAR:9:4}
eric

# variable name wildcards

$ echo ${!MY*}
MYVAR

$ echo ${!DI*}
DIRSTACK DISPLAY

# '##' removes a prefix (accepts wildcards)

$ echo ${MYVAR##/usr}
/bin/eric.rocks

$ pwd
/usr/bin

$ echo ${MYVAR##$( pwd )}
/eric.rocks

# '%' remove the suffix (non-greedy)

$ echo ${MYVAR%.rocks}
/usr/bin/eric

# '%%' removes it greedily

$ echo ${MYVAR%r*}
/usr/bin/eric.

$ echo ${MYVAR%%r*}
/us

$ echo ${MYVAR%%ic}
/usr/bin/eric.rocks

$ echo ${MYVAR%%ic*}
/usr/bin/er

Substitution

${parameter/pattern/string}

# pattern accepts filename-type wildcards

$ echo ${MYVAR/e/f}
/usr/bin/fric.rocks

$ echo ${MYVAR/e*c/f}
/usr/bin/fks

# '#' means match from beginning

$ echo ${MYVAR/#\/*c/f}
fks

# '//' means replace all instances

$ $ echo ${MYVAR/S/e}                                  
ACCEeS DENIED

$ echo ${MYVAR//S/e}                                 
ACCEee DENIED

Transformations

# '^^' uppercases it

$ echo ${MYVAR^^}
/USR/BIN/ERIC.ROCKS

$ echo ${MYVAR^*}
/usr/bin/eric.rocks

$ echo ${TERM^*}
Screen

# ',' and ',,' lowercases it

$ export MYVAR="ACCESS DENIED"

$ echo ${MYVAR,}

aCCESS DENIED

$ echo ${MYVAR,,} 
access denied

Returning Default Values

$ export MYVAR=/usr/bin/eric.rocks

$ unset NULLVAR

# return default "test" if unset

$ echo ${MYVAR:-test}
/usr/bin/eric.rocks

# return default value if unset

$ echo ${NULLVAR:-test}
test

# return, and assign, default value if unset

$ echo ${NULLVAR:=test}
test

$ set |grep NULLVAR
NULLVAR=test

$ unset NULLVAR

# return error message if unset

$ echo ${NULLVAR?aaaaaah}
-bash: NULLVAR: aaaaaah

# return value if set

$ echo ${MYVAR:+$TERM}
screen

# return nothing if unset

$ echo ${NULLVAR:+$TERM}

Read more

I should have called this, how to kick sed off my living room couch, and tell that lazy scumbag to go out and get a job and stop drinking all my beer. But that was too long.

TL;DR

You can do just about anything inside two {}'s; the laws of nature no longer apply in there..

Substrings

$ export MYVAR=/usr/bin/eric.rocks

$ unset NULLVAR

$ echo ${MYVAR:1}
usr/bin/eric.rocks

$ echo ${MYVAR:9}
eric.rocks

$ echo ${MYVAR:9:4}
eric

# variable name wildcards

$ echo ${!MY*}
MYVAR

$ echo ${!DI*}
DIRSTACK DISPLAY

# '##' removes a prefix (accepts wildcards)

$ echo ${MYVAR##/usr}
/bin/eric.rocks

$ pwd
/usr/bin

$ echo ${MYVAR##$( pwd )}
/eric.rocks

# '%' remove the suffix (non-greedy)

$ echo ${MYVAR%.rocks}
/usr/bin/eric

# '%%' removes it greedily

$ echo ${MYVAR%r*}
/usr/bin/eric.

$ echo ${MYVAR%%r*}
/us

$ echo ${MYVAR%%ic}
/usr/bin/eric.rocks

$ echo ${MYVAR%%ic*}
/usr/bin/er

Substitution

${parameter/pattern/string}

# pattern accepts filename-type wildcards

$ echo ${MYVAR/e/f}
/usr/bin/fric.rocks

$ echo ${MYVAR/e*c/f}
/usr/bin/fks

# '#' means match from beginning

$ echo ${MYVAR/#\/*c/f}
fks

# '//' means replace all instances

$ $ echo ${MYVAR/S/e}                                  
ACCEeS DENIED

$ echo ${MYVAR//S/e}                                 
ACCEee DENIED

Transformations

# '^^' uppercases it

$ echo ${MYVAR^^}
/USR/BIN/ERIC.ROCKS

$ echo ${MYVAR^*}
/usr/bin/eric.rocks

$ echo ${TERM^*}
Screen

# ',' and ',,' lowercases it

$ export MYVAR="ACCESS DENIED"

$ echo ${MYVAR,}

aCCESS DENIED

$ echo ${MYVAR,,} 
access denied

Returning Default Values

$ export MYVAR=/usr/bin/eric.rocks

$ unset NULLVAR

# return default "test" if unset

$ echo ${MYVAR:-test}
/usr/bin/eric.rocks

# return default value if unset

$ echo ${NULLVAR:-test}
test

# return, and assign, default value if unset

$ echo ${NULLVAR:=test}
test

$ set |grep NULLVAR
NULLVAR=test

$ unset NULLVAR

# return error message if unset

$ echo ${NULLVAR?aaaaaah}
-bash: NULLVAR: aaaaaah

# return value if set

$ echo ${MYVAR:+$TERM}
screen

# return nothing if unset

$ echo ${NULLVAR:+$TERM}

Read more

LXC is a container-type technology built into the Linux kernel, with userspace available on Ubuntu, and probably most other modern distributions. It is not virtualization as such, but it will let you set up development environments very quickly.

It is good for setting up test web applications, running databases, checking packaging issues, that sort of thing. You can also use it to place a more secure, minimal environment around applications that communicate with the outside world.

It is not good for deeper testing, or anything that requires virtualized block or network devices, such as OpenVPN. If you've had openvz or virtuozzo containers before, you'll be aware of these gotchas.

To test it out on Natty, just do the following:

apt-get install lxc

You'll need to setup on configuration file. The easiest way is to use "macvlan" as your networking type.

# cat /etc/lxc/lxc-macvlan.conf
lxc.network.type = macvlan
lxc.network.flags = up
lxc.network.link = eth0

To see what kind of mischief you can get into, check the directory /usr/lib/lxc/templates/ . Strip off the "lxc-", and use the remaining name create a new container.

This works like this:

 lxc-create -n lxc-natty -f /etc/lxc/lxc-macvlan.conf -t natty

You'll see output like the following:

debootstrap is /usr/sbin/debootstrap
Checking cache download in /var/cache/lxc/natty/rootfs-amd64 ...
Downloading ubuntu natty minimal ...
I: Retrieving Release
I: Retrieving Packages
...

This takes a bit of time, since it's downloading packages and setting them up. This is cached however. The next time you setup a container using that template, it goes lightning-fast, for values of lightning around 5 seconds.

Once this gets through bootstrapping the container, you'll be left with a directory under /var/lib/lxc/lxc-natty (in this case). The actual container's root filesystem is under the subdirectory rootfs/ . Use chroot to prepare the environment a little before booting it up.

chroot /var/lib/lxc/lxc-natty/rootfs/
adduser eric
...
gpasswd -a eric sudo
apt-get install -y ubuntu-minimal
...
exit

LXC uses cgroups to keep itself out of trouble. It will control these using any mounted cgroup pseudo-filesystem it comes across. Just mount one on /cgroups/ and it will find it with no issues:

mkdir /cgroups
mount cgroups -t cgroup /cgroups
mount |grep cgroup

At this point, you can boot your LXC instance up and have a look around. Since LXC containers take over the current TTY, it's a good idea to create a new screen session to house the different consoles. This lets you login directly in case you break your network or SSH configuration.

(in a screen session)
lxc-start -n lxc-natty
...
login:

Now you can login to the user account you supplied with the adduser command earlier. Do a quick ifconfig, and you'll be able to login to your instance with SSH.

Update — 19 October 2011

Oneiric adds some features to lxc, and the syntax changes a bit for creating LXC containers. To create a new container, do the following:

lxc-create -f /etc/lxc/lxc-veth.conf -t ubuntu -n oneiric1

To specify a release besides the current one, use -r $release, e.g.:

lxc-create -f [...] -t ubuntu -n oneiric -- -r natty

Read more

LXC is a container-type technology built into the Linux kernel, with userspace available on Ubuntu, and probably most other modern distributions. It is not virtualization as such, but it will let you set up development environments very quickly.

It is good for setting up test web applications, running databases, checking packaging issues, that sort of thing. You can also use it to place a more secure, minimal environment around applications that communicate with the outside world.

It is not good for deeper testing, or anything that requires virtualized block or network devices, such as OpenVPN. If you've had openvz or virtuozzo containers before, you'll be aware of these gotchas.

To test it out on Natty, just do the following:

apt-get install lxc

You'll need to setup on configuration file. The easiest way is to use "macvlan" as your networking type.

# cat /etc/lxc/lxc-macvlan.conf
lxc.network.type = macvlan
lxc.network.flags = up
lxc.network.link = eth0

To see what kind of mischief you can get into, check the directory /usr/lib/lxc/templates/ . Strip off the "lxc-", and use the remaining name create a new container.

This works like this:

 lxc-create -n lxc-natty -f /etc/lxc/lxc-macvlan.conf -t natty

You'll see output like the following:

debootstrap is /usr/sbin/debootstrap
Checking cache download in /var/cache/lxc/natty/rootfs-amd64 ...
Downloading ubuntu natty minimal ...
I: Retrieving Release
I: Retrieving Packages
...

This takes a bit of time, since it's downloading packages and setting them up. This is cached however. The next time you setup a container using that template, it goes lightning-fast, for values of lightning around 5 seconds.

Once this gets through bootstrapping the container, you'll be left with a directory under /var/lib/lxc/lxc-natty (in this case). The actual container's root filesystem is under the subdirectory rootfs/ . Use chroot to prepare the environment a little before booting it up.

chroot /var/lib/lxc/lxc-natty/rootfs/
adduser eric
...
gpasswd -a eric sudo
apt-get install -y ubuntu-minimal
...
exit

LXC uses cgroups to keep itself out of trouble. It will control these using any mounted cgroup pseudo-filesystem it comes across. Just mount one on /cgroups/ and it will find it with no issues:

mkdir /cgroups
mount cgroups -t cgroup /cgroups
mount |grep cgroup

At this point, you can boot your LXC instance up and have a look around. Since LXC containers take over the current TTY, it's a good idea to create a new screen session to house the different consoles. This lets you login directly in case you break your network or SSH configuration.

(in a screen session)
lxc-start -n lxc-natty
...
login:

Now you can login to the user account you supplied with the adduser command earlier. Do a quick ifconfig, and you'll be able to login to your instance with SSH.

Read more

So, you've got yourself a fancy new Thinkpad x220 or T520, and you're trying to get Ubuntu running on it.

Intel's Sandy Bridge platform isn't widely supported in the Linux world yet. If you're running Ubuntu's current release, Natty, it will work without much fuss. You might just need to update xorg's Intel graphic driver and libdrm from a suitable PPA. To get the full 3D acceleration, you'll also want to get betting familiar with the X220 Mesa PPA.

If you're running Lucid LTS 10.04, you'll need to grab the backported Natty kernel from the Ubuntu Kernel Team's PPA, as well as the updated Mesa libraries.

Here's how to add them and update your drivers:

apt-add-repository ppa:kernel-ppa/ppa
apt-add-repository ppa:glasen/intel-driver
apt-add-repository ppa:f-hackenberger/x220-intel-mesa

apt-get update
apt-get install -y linux-image-generic-pae-lts-backport-natty
apt-get dist-upgrade -y

This will give you a fully-working desktop with accelerated 3D graphics and the swhooshy Desktop Effects.

Mind you, you'll be running a configuration that isn't supported by Canonical, and isn't an official distribution any more. The best way to stay supported is to buy supported hardware, like a non-Sandy Bridge laptop or one of the many that are based on AMD CPUs.

Read more

So, you've got yourself a fancy new Thinkpad x220 or T520, and you're trying to get Ubuntu running on it.

Intel's Sandy Bridge platform isn't widely supported in the Linux world yet. If you're running Ubuntu's current release, Natty, it will work without much fuss. You might just need to update xorg's Intel graphic driver and libdrm from a suitable PPA. To get the full 3D acceleration, you'll also want to get betting familiar with the X220 Mesa PPA.

If you're running Lucid LTS 10.04, you'll need to grab the backported Natty kernel from the Ubuntu Kernel Team's PPA, as well as the updated Mesa libraries.

Here's how to add them and update your drivers:

apt-add-repository ppa:kernel-ppa/ppa
apt-add-repository ppa:glasen/intel-driver
apt-add-repository ppa:f-hackenberger/x220-intel-mesa

apt-get update
apt-get install -y linux-image-generic-pae-lts-backport-natty
apt-get dist-upgrade -y

This will give you a fully-working desktop with accelerated 3D graphics and the swhooshy Desktop Effects.

Mind you, you'll be running a configuration that isn't supported by Canonical, and isn't an official distribution any more. The best way to stay supported is to buy supported hardware, like a non-Sandy Bridge laptop or one of the many that are based on AMD CPUs.

Read more

When you enable the Expose-like feature under Unity (Default Super+W), you'll see all of your windows tiled about the screen, allowing you to pick them easily.

The more windows you have open, however, the smaller the preview windows become. The fact that almost all applications have a fairly consistent look and feel might be good for the general desktop experience, but it's not very good for picking out which windows belong to which application.

Without icon overlays

One way to get around this is to overlay the application icon on the window itself. Unfortunately, the Unity itself doesn't have a configuration UI for this, so you'll need to do it at the Compiz level. To do this, install the package compizconfig-settings-manager:

apt-get install compizconfig-settings-manager

Now run the command, either using the launcher or typing "ccsm" into the terminal. Go the conrol panel called "Scale" under "Window Management", and set the "Overlay Icon" option. I personally prefer "Emblem", as it makes it easier to pick out the icon.

With icon overlays

Voila, usable Expose.

Read more

When you enable the Expose-like feature under Unity (Default Super+W), you'll see all of your windows tiled about the screen, allowing you to pick them easily.

The more windows you have open, however, the smaller the preview windows become. The fact that almost all applications have a fairly consistent look and feel might be good for the general desktop experience, but it's not very good for picking out which windows belong to which application.

Without icon overlays

One way to get around this is to overlay the application icon on the window itself. Unfortunately, the Unity itself doesn't have a configuration UI for this, so you'll need to do it at the Compiz level. To do this, install the package compizconfig-settings-manager:

apt-get install compizconfig-settings-manager

Now run the command, either using the launcher or typing "ccsm" into the terminal. Go the conrol panel called "Scale" under "Window Management", and set the "Overlay Icon" option. I personally prefer "Emblem", as it makes it easier to pick out the icon.

With icon overlays

Voila, usable Expose.

Read more

Gwibber Screenshot

Why are there monkeys?

Read more

Gwibber Screenshot

Why are there monkeys?

Read more