5

First time using serverfault, please excuse any breaches of etiquette.

I've created several LVM2 logical volumes in local storage on a server, and would like one of the device nodes - not the filesystem or mount point - to be owned by a user/group other than root:root.

This is pretty much a default RHEL5 server. I understand that the device node is created dynamically at boot time after LVM scans the disks for pv/vg/lvs. I'm not really sure how udev, mapper, and lvm interact to create these nodes, and the configuration file specs are a little cryptic for someone without much experience.

There will be more lvs to follow that also need alternate permissions, but I'd ideally like to keep the other lvs in the volume group at root:root, and only change specific ones.

Can anyone help me figure this one out? I've been googling for hours.

Thanks in advance, Tony


Update:

I accomplished this through the following. It may be a roundabout way of doing things, but this is only a temporary environment (famous last words!). Oh, I may also want to remove the lines that print to /tmp/foo.

[root@xxxxxxx rules.d]# **cat /etc/udev/rules.d/11-lvm.rules**
ACTION=="add|change", KERNEL=="dm-*", PROGRAM="/bin/sh -c /etc/udev/scripts/oracle_perms.sh"

[root@xxxxxxx rules.d]# **cat /etc/udev/scripts/oracle_perms.sh**
#!/bin/bash

echo "DEVPATH=$DEVPATH" >> /tmp/foo
MAJMIN=`cat /sys${DEVPATH}/dev`
echo "MAJMIN=$MAJMIN" >> /tmp/foo
MAJ=`echo ${MAJMIN} | awk -F: '{ print $1 }'`
MIN=`echo ${MAJMIN} | awk -F: '{ print $2 }'`
DEVNODE=`/sbin/dmsetup info -j ${MAJ} -m ${MIN} | grep Name | awk '{ print $2 }'`
echo "DEVNODE=${DEVNODE}" >> /tmp/foo
echo "${DEVNODE}" | grep ora >/dev/null 2>&1
if [ "$?" == "0" ]; then
  echo "Making change...." >> /tmp/foo
  chown oracle:dba /dev/mapper/${DEVNODE}
  chmod 660 /dev/mapper/${DEVNODE}
  ls -l /dev/mapper/${DEVNODE} >> /tmp/foo
else
  echo "No 'ora' name detected. No change necessary." >> /tmp/foo
fi

Note that the solution above automagically changes ANY LV that's created with "ora" in the name. Hey, it works for now.

  • 1
    out of curiosity, what in the world are you trying to accomplish? :) – Chad Huneycutt Aug 07 '09 at 20:55
  • I'm trying to set up the LV as a data store for our DBA to configure an Oracle ASM partition. According to the docs I've seen, the raw device setup doesn't need to be done anymore as Oracle now uses O_DIRECT to address the device directly. I understand that Oracle supports, but does not recommend, ASM on top of LVM, but we're stuck with local storage on a system where the default build gives all the disk space to LVM until we can get the SAN connections made. –  Aug 07 '09 at 20:59

1 Answers1

2

The following should work (adapt as necessary):

# cat /etc/udev/rules.d/99-custom.rules
ENV{DM_NAME}=="system-test", ACTION=="add|change", MODE="0664", OWNER="michael", GROUP="disk", PROGRAM="/bin/logger /dev/$env{DM_NAME} owner changed to michael", SYMLINK+="oracle-$env{DM_NAME}"

Then you should get the result:

# lvcreate -L 1G /dev/system -n test
# ls -al /dev/dm-9 /dev/oracle-system-test /dev/system/test /dev/mapper/system-test
brw-rw-r-- 1 michael disk 253, 9 2009-08-08 01:20 /dev/dm-9
brw-r----- 1 root    disk 253, 9 2009-08-08 01:20 /dev/mapper/system-test
lrwxrwxrwx 1 root    root      4 2009-08-08 01:20 /dev/oracle-system-test -> dm-9
lrwxrwxrwx 1 root    root     23 2009-08-08 01:20 /dev/system/test -> /dev/mapper/system-test

I wasn't able to figure out how to modify the actual device node created by LVM, but I was able to modify the device-mapper node. I then added a symlink for oracle to access it with which is a bit of a hack, but works.

(my earlier answer was a little rushed and untested. But I got really curious how to do it right :)

MikeyB
  • 38,725
  • 10
  • 102
  • 186
  • Certainly seems like it should work that way, however here's what I get: # cat /etc/udev/rules.d/11-lvmowner.rules NAME="mapper/rootvg-asmtest", MODE="0660", OWNER="oracle", GROUP="dba" # udevcontrol reload_rules # lvcreate -L 1G /dev/rootvg -n asmtest Logical volume "asmtest" created # ls -l /dev/rootvg/asmtest lrwxrwxrwx 1 root root 26 Aug 7 17:31 /dev/rootvg/asmtest -> /dev/mapper/rootvg-asmtest # ls -l /dev/mapper/rootvg-asmtest brw-rw---- 1 root disk 253, 13 Aug 7 17:31 /dev/mapper/rootvg-asmtest Did I not use the correct name, possibly? –  Aug 07 '09 at 21:37
  • I keep trying to edit the formatting - tried pre and br tags, and tried indenting the pasted lines 4 spaces. Sorry, still getting the hang of this. –  Aug 07 '09 at 21:47
  • Just update your post with the info. – Chad Huneycutt Aug 07 '09 at 23:23
  • By the way, I highly recommend the udev(7) manpage. udev rules can be very cryptic, but this example should give you an idea of how to do corner cases without being too complicated. – MikeyB Aug 08 '09 at 05:26
  • MikeyB: Thanks for your continued help in chasing this down. I've taken a look at the udev manpage, and think I have a very basic understanding of how the udev rules work. However, I've tried several juxtapositions of your examples and a few tests on my own, and I don't think I've been able to properly capture the devices. I'm not sure if another rule is shortcutting mine, or if I'm not specifying the correct key to determine when the rule should apply. Can you tell me how the LVs look to udev when they're first sent there, or what part of your sample rule should capture that? Thanks again. –  Aug 10 '09 at 17:43