MythTV Update
I just updated my MythTV box from Karmic to Lucid. There were a few things that needed updating, and it became a little like pulling on a piece of thread - one thing lead to another until it became quite the saga. I thought I'd document things so that others don't have quite the same pain.
There were two big things that changed: I updated my data store filesystem from zfs to btrfs. I updated my lirc configuration to use the new devinput driver.
zfs to btrfs
My machine has one 64Gb SSD with the root filesystem (ext4), and two 1Tb HDDs. Under Karmic I was using zfs-fuse on the HDDs in a raid1 (mirrored) configuration. They were one big pool, but I then had a number of filesystems on that pool that I could mount in different places - e.g. /var/lib, /home, /srv, etc. I had to do this because zfs-fuse gets harder to use the earlier you try to load it. By just using it for sections of the directory structure that load relatively late it was possible to use it for large data stores, but still have it be relatively easy to use.
Under lucid, zfs-fuse is now in the ubuntu repository, rather than an extra ppa. This made me think that the setup was likely to keep working... unfortunately that wasn't the case. After the dist-upgrade I ended up with a problem whereby certain of my zfs filesystems didn't show up in a zfs list and didn't mount with a mount -a. Given that I knew the names of some of the filesystems, I could mount them, but I didn't remember the names of some of the snapshots, and I couldn't figure out how to list them... so I decided to move to btrfs.
I've been thinking about switching to btrfs for a while. Having something natively supported in the kernel is likely to be faster, and I suspect the support on linux will be better. The question is then how to move from a raid1 zfs setup to a raid1 btrfs setup. Given that they're both raid1, you'd think it would be easy. Unfortunately, btrfs cannot currently add a second disk in a raid1 configuration after the filesystem creation - you have to have two disks at creation time. So I used a loopback device backed by a sparse file as my second device...
btrfs raid1 array creation
The two drives we're talking about are /dev/sdb and /dev/sdc. I initially removed /dev/sdb from the zfs pool leaving the pool in degraded mode. Then I did the following to turn /dev/sdb into the start of the btrfs pool: (I was basing this on the btrfs information here: http://btrfs.wiki.kernel.org/index.php/Using_Btrfs_with_Multiple_Devices)
# get the size of the disk you want to move from (in 1k blocks)
cat /proc/partitions # look for /dev/sdb1
# create the large, sparse data file
dd if=/dev/zero of=large.img bs=1k count=1 seek=<size of disk in blocks>
# mount it on a loopback device
losetup /dev/loop0 large.img
# make the raid1 btrfs filesystem
mkfs.btrfs -m raid1 -d raid1 /dev/sdb1 /dev/loop0
# mount the filesystem once
mount -t btrfs /dev/sdb1 btrfs-mnt
# if that didn't work, try mounting it using /dev/loop0
# then unmount it again
umount btrfs-mnt
# undo the loopback setup
losetup -d /dev/loop0
# remove the sparse file
rm large.img
# mount the drive again in degraded mode
mount -t btrfs -odegraded /dev/sdb1 btrfs-mnt
# make btrfs subvolumes and copy stuff onto the drive
cp -rp stuff btrfs-mnt/
# unmount zfs
# use gparted to re-partition /dev/sdc into one big partition
then I tried the following, which didn't work:
btrfs-vol -a /dev/sdc1 btrfs-mnt
btrfs-vol -r missing btrfs-mnt
# remount btrfs volumes in the right places and not in degraded mode
This began a saga trying to make btrfs to work as a raid1 system. Luckily, all my data was there and accessible on /dev/sdb1 in degraded mode (although I had a few heart-stopping moments - this procedure is for the brave at the moment).
The solution ended up being to update to a newer version of btrfs :). Lucid runs kernel 2.6.32 which was just as btrfs became at all usable, and it still appears to have some issues. I wanted to update to at least 2.6.34 and preferably newer.
There are two parts to btrfs - the kernel and the tools. I updated the tools by downloading the latest source package (for Natty) for btrfs-tools from https://launchpad.net/ubuntu/+source/btrfs-tools and building it locally on Lucid. It built just fine.
I also updated to a backported natty kernel. I added the ubuntu kernel ppa from https://launchpad.net/~kernel-ppa/+archive/ppa and then installed the linux-image-generic-lts-backport-natty package and associated headers.
Once these updates were done I was able, with only a little bit of playing, to get /dev/sdc1 added to the btrfs pool using the new style btrfs commands.
Remember to re-balance after adding the new drive to copy all the data across both.
There is still a weird issue removing the 'missing' devices - I don't get an error, but the 'missing' devices are still flagged as 'missing':
root@willvo:~# btrfs filesystem show
failed to read /dev/sr0
Label: none uuid: f929c413-01c8-443f-b4f2-86f36702f519
Total devices 3 FS bytes used 578.39GB
devid 1 size 931.51GB used 604.00GB path /dev/sdb1
devid 2 size 931.51GB used 604.00GB path /dev/sdc1
*** Some devices missing
Btrfs Btrfs v0.19
root@willvo:~# btrfs device delete missing /data
root@willvo:~# btrfs filesystem show
failed to read /dev/sr0
Label: none uuid: f929c413-01c8-443f-b4f2-86f36702f519
Total devices 3 FS bytes used 578.39GB
devid 1 size 931.51GB used 604.00GB path /dev/sdb1
devid 2 size 931.51GB used 604.00GB path /dev/sdc1
*** Some devices missing
Btrfs Btrfs v0.19
But it seems to be working anyway, so we'll leave that for the moment and move to the other issue. The new kernel doesn't just change the way btrfs works - it also changes the IR drivers. That means an update to the lirc configuration.
Updating lirc
The backstory for this update is covered here, http://wilsonet.com/?page_id=95, but the short story is that the drivers have changed and you need to switch to using devinput.
I have an Antec Veris system with a imon IR receiver and an Antec_Veris_RM200 remote. I don't actually use that remote though - it has too many keys and that just invites people to either a) complain it is too complex, b) press the keys and complain they don't do anything or c) both of the previous. Rather I use a LogiTech Harmony 525 programmable remote.
When I first set up my system, Logitech's auto-setup system didn't know about the RM200 remote - I had to use their learning system to program the Harmony. This worked ok, but I was never quite satisfied with it. When I set things up this time I figured out that with the new drivers I can switch the receiver into 'rc-6' mode which allows it to understand Microsoft Media Centre remotes. This is great as Logitech certainly does know about them. I followed this guide to set up my remote to act as a media-centre remote. I found there were a few buttons that my system couldn't interpret, so I had to switch some around - that wasn't a problem as there are plenty of options to choose from and most work just fine (but see below). One other caveat is that I couldn't get any of the 'Microsoft Keyboard' buttons to work reliably, just the remote buttons.
The setup on the linux side is a little more tricky. I found this thread useful, but did not follow it exactly.
Firstly, you need the ir-keytable tool, which I had to build from source.
git clone http://linuxtv.org/git/v4l-utils.git
cd v4l-utils
make
cd utils/keytable
cp ir-keytable /usr/local/bin/
cp rc_keymaps /etc/
Then when you run it, it will tell you the device to use for your remote:
# ir-keytable
Found /sys/class/rc/rc0/ (/dev/input/event4) with:
Driver imon, table rc-imon-pad
Supported protocols: RC-6 Enabled protocols:
But we don't want to use /dev/input/event4 directly as that may change when you connect or disconnect another input device. Rather, use ls -l /dev/input/by-id/ to see which device there points to the right device. In my case I want to use /dev/input/by-id/usb-15c2_0038-event-mouse because that points to /dev/input/event4, but will keep pointing to the right device even if it changes.
Now, switch your lirc configuration to using devinput:
sudo dpkg-reconfigure lirc
and then select
Linux input layer (/dev/input/eventX)
I selected None for the IR Transmitter, and then /dev/input/by-id/usb-15c2_0038-event-mouse for the device.
Next, we need to tell HAL not to grab the device. Following the advice here I looked in /usr/share/hal/fdi/preprobe/20thirdparty/ and noticed there was already a lirc.fdi file. I edited it to add the following:
<match key="info.product" contains_ncase="iMON Remote">
<merge key="info.ignore" type="bool">true</merge>
</match>
Next, we need to switch the remote into rc-6 mode and update its keymap. This can be done using the ir-keytable command we built earlier. For example:
ir-keytable -c -w /etc/rc_keymaps/imon_mce
should do both. I had some problems with that however and played around with a few things. I'm not exactly sure which of these fixed the problems.
- At the top of the keymap, you'll notice it has a
type: RC6. If you feed that toir-keytable -p, then you sometimes seem to get an error. I think this should beRC-6. - Secondly, a bunch of keys didn't work. In the end I made my own keymap file,
imon_will, with the type changed toRC-6, all the keycodes fromimon_mceand all the keycodes fromrc6_mce - Then you need to make sure the new keymap is loaded. I did this with brute force: I added the line
/usr/local/bin/ir-keytable -c -w /etc/rc_keymaps/imon_willto/etc/init.d/lirc
And even that isn't enough to make the whole system work. I still found that lirc wasn't getting some keys. So I copied /usr/share/lirc/remotes/devinput/lircd.conf.devinput to /etc/lirc/lircd.conf.devinput and edited it as follows (basically adding 0x200 to some of the event codes - not sure why they need this):
--- /usr/share/lirc/remotes/devinput/lircd.conf.devinput 2009-02-08 05:00:41.000000000 +1100
+++ /etc/lirc/lircd.conf.devinput 2010-10-30 00:45:19.529971238 +1100
@@ -11,20 +11,21 @@
pre_data_bits 16
pre_data 0x8001
gap 132799
+# gap 39995
toggle_bit_mask 0x0
begin codes
- KEY_0 0x000B
KEY_102ND 0x0056
- KEY_1 0x0002
- KEY_2 0x0003
- KEY_3 0x0004
- KEY_4 0x0005
- KEY_5 0x0006
- KEY_6 0x0007
- KEY_7 0x0008
- KEY_8 0x0009
- KEY_9 0x000A
+ KEY_0 0x0200
+ KEY_1 0x0201
+ KEY_2 0x0202
+ KEY_3 0x0203
+ KEY_4 0x0204
+ KEY_5 0x0205
+ KEY_6 0x0206
+ KEY_7 0x0207
+ KEY_8 0x0208
+ KEY_9 0x0209
KEY_A 0x001E
KEY_AB 0x0196
KEY_AGAIN 0x0081
@@ -191,7 +192,8 @@
KEY_KP7 0x0047
KEY_KP8 0x0048
KEY_KP9 0x0049
- KEY_KPASTERISK 0x0037
+# KEY_KPASTERISK 0x0037
+ KEY_KPASTERISK 0x020A
KEY_KPCOMMA 0x0079
KEY_KPDOT 0x0053
KEY_KPENTER 0x0060
@@ -200,7 +202,8 @@
KEY_KPLEFTPAREN 0x00B3
KEY_KPMINUS 0x004A
KEY_KPPLUS 0x004E
- KEY_KPPLUSMINUS 0x0076
+# KEY_KPPLUSMINUS 0x0076
+ KEY_KPPLUSMINUS 0x020B
KEY_KPRIGHTPAREN 0x00B4
KEY_KPSLASH 0x0062
KEY_L 0x0026
Having made those changes you still need to tell lirc to use them, so edit /etc/lirc/lircd.conf to include /etc/lirc/lircd.conf.devinput instead of the default (for devinput) /usr/share/lirc/remotes/devinput/lircd.conf.devinput.
At this point your remote should work.
Lirc and gdm
There is one other tweak I made. I still use gdm on my system rather than booting directly into mythtv. I have the mythtv user set up to auto-login after 10 seconds. Before Karmic, this used to wait 10 seconds and then start mythtv every time. On Karmic and now Lucid, this only auto-login only works on the initial boot. If you exit myth then it will not re-auto-login. As I have no easily accessible keyboard, this is somewhat annoying.
I just added some extra irexec commands that run on KEY_UP, KEY_DOWN and KEY_OK events. These check if the 'mythtv' user is logged in, and if not then they use xdotool to generate approprate keyboard events. This allows you to use the remote to select the myth user. On Lucid you can then add that user to the nopasswdlogin group so that they don't need a password to login on the console (you want to make sure your remote access is still secure!), and people can now restart the myth frontend effectively with just the remote.