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:
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).
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:
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:
Here is the link to updated rules file: evms.rules.new
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)all your initramfs needs to do is to:
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}"
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:
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:
Update 04.05.2006:
After talking to guys from linux-hotplug, the following changes have been made:
# Do not create device-mapper nodesand emvs.rules file now looks like following:
KERNEL=="dm-[0-9]*", NAME+=""
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
0 Comments:
Post a Comment
<< Home