.comment-link {margin-left:.6em;}

Linux stories... and more

Monday, May 01, 2006

Fine-grained EVMS device nodes

Recently I've finally started to use EVMS for Volume Management. In this article, I'll explain how I've managed to marry EVMS with udev :).

First, I'd like to mention how my LFS-based systems boot: I distinguish "my" root file system by UUID. I.e. on kernel command line instead of root=LABEL=/root you supply UUID=543fcb1d-b73c-4f7b-8e00-1f92b232d188, which is the UUID of the partition that holds your root. Usually, initramfs image that does all of the magic, has hard-coded UUID of the root file system it was built from.

Next task was to make initramfs to discover file systems by their UUID. With recent udev rules, its rather easy. With the following rules from /etc/udev/rules.d/60-persistent-storage.rules:
# by-label/by-uuid (filesystem properties)
KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="persistent_storage_end"
IMPORT{program}="/sbin/vol_id --export $tempnode" ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}"
ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}"
all your initramfs needs to do is to:
  • load storage drivers
  • setup udev environment
  • finally, just look at /dev/disk/by-uuid/$UUID
    Back to EVMS. I've thought that all I'll need to do in order to add EVMS support to my initramfs is just to add evms_activate command. I was very surprised that my EVMS volumes did not show up under /dev/disk/by-uuid/.
    I've started to dig... Conclusions:
  • EVMS does not send any uevents, but
  • It uses device-mapper to export device nodes - this looks promising
    So, EVMS works together with device-mapper - for each EVMS object (i.e. Volume, Container, Segment, etc...) device mapper exports sysfs entry /sys/block/dm-*, which is picked up by udev and /dev/dm-<number> is created.

    Having a closer look at /etc/udev/rules.d/60-persistent-storage.rules I've found the following rule, which provides /dev/disk/by-name (does not help much).
    KERNEL=="dm-[0-9]*", ACTION=="add",     PROGRAM="/sbin/dmsetup info -c --noopencount                                    --noheadings -o name -j %M -m %m",     SYMLINK="disk/by-name/%c"

    Note, that the rule uses SYMLINK=... and not SYMLINK+=... action. That's why further matching rules are not applied.

    Take one: Change SYMLINK=... to SYMLINK+=... in the above rule.

    Great. The results are almost perfect - now all /dev/dm-0 device files have corresponding links in /dev/disk/by-uuid, BUT(!)...

    But... As I've mentioned earlier, device mapper has /dev/dm-* for each EVMS object. So lets say you have /dev/dm-1, which actually EVMS region, and /dev/dm-2 which a EVMS volume (that sit on the mentioned region) that contains valid file system.
    The bad news are, that running /sbin/vol_id --export will return the same sane results both for /dev/dm-1 and /dev/dm-2. But mounting of /dev/dm-1 will obviously fail (since it is not volume, but region).
    So the actual problem is that if your volume has UUID=<what_ever>,
    then /dev/disk/by-uuid/$UUID may point either to /dev/dm-1 or to /dev/dm-2, and in the first case, mounting /dev/disk/by-uuid/$UUID will fail!

    So we need to distinguish between dm-* devices that point to volumes and others. How? - All active volumes has corresponding device nodes in /dev/emvs/. That directory is managed by EVMS user-space tools.
    So for each dm-* node we first retrieve its name using dmsetup and then, if /dev/evms/<name> exists, we create /dev/disk... links.

    Take two: I've created separate udev rules file, 61-evms.rules, which has the following rules:
    KERNEL=="dm-[0-9]*",    ACTION=="add",    IMPORT{program}="/bin/sh -c 'echo DMNAME=`(/sbin/dmsetup info -c                     --noopencount --noheadings -o name -j %M -m %m`'"
    KERNEL=="dm-[0-9]*", ACTION=="add", IMPORT{program}="/sbin/vol_id --export $tempnode"
    KERNEL=="dm-[0-9]*", ACTION=="add", ENV{ID_FS_UUID}=="?*",PROGRAM="/bin/test -e /dev/evms/$env{DMNAME}", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}"
    KERNEL=="dm-[0-9]*", ACTION=="add", ENV{ID_FS_LABEL_SAFE}=="?*", PROGRAM="/bin/test -e /dev/evms/$env{DMNAME}", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}"

    Related links:
  • evms.rules file
  • mkinitramfs project that creates all those "magic" images.
    Update 04.05.2006:
    After talking to guys from linux-hotplug, the following changes have been made:
  • /dev/dm-* device nodes are not needed
  • links should be created to /dev/evms/* files and not to /dev/dm-* files.So the line considering dmsetup in the 60-persistent-storage.rules was replaced with the following:
    # Do not create device-mapper nodes
    KERNEL=="dm-[0-9]*", NAME+=""
    and emvs.rules file now looks like following:
    KERNEL=="dm-[0-9]*",    ACTION=="add", IMPORT{program}="/bin/bash -c 'echo DMNAME=$$(/sbin/dmsetup info -c                     --noopencount --noheadings -o name -j %M -m %m)'"
    KERNEL=="dm-[0-9]*", ACTION=="add", IMPORT{program}="/sbin/vol_id --export $tempnode"
    KERNEL=="dm-[0-9]*", ACTION=="add", ENV{ID_FS_UUID}=="?*", PROGRAM="/bin/test -e /dev/evms/$env{DMNAME}", RUN+="/bin/ln -sf /dev/evms/$env{DMNAME} /dev/disk/by-uuid/$env{ID_FS_UUID}"
    KERNEL=="dm-[0-9]*", ACTION=="add", ENV{ID_FS_LABEL_SAFE}=="?*", PROGRAM="/bin/test -e /dev/evms/$env{DMNAME}", RUN+="/bin/ln -sf /dev/emvs/$env{DMNAME} /dev/disk/by-label/$env{ID_FS_LABEL_SAFE}"

    Here is the link to updated rules file: evms.rules.new

  • bug in konsole

    As a 'die-hard' KDE user, I use konsole application on every day basis. A long time a go I've run into a strange problem - I've failed to change default konsole session - it always remains shell.desktop.

    Looking down to config files, I've found that there is a DefaultSession parameter in konsolerc that is responsible for setting the default session. But the problem is that konsole just ignores this paramter.

    Source code inverstigaion showed that upon startup, konsole indeed ignores DefaultSession setting and just always sets shell.desktop to be the default session.

    Well, if it does not work - fix it yourself :) So I've created the patch (against kde-3.5.2) and opened the bug.

    Update 04.05.2006:
    The patch has been accepted upstream and the bug has been closed.