Thursday, March 18, 2010

access files below a mountpoint

Today I needed to be able to access a directory that is normally used as a mountpoint. I needed to do this because we wanted to transition some automounts to hardmounts without interruption.

So an example is we have auto mount table /test specfied in /etc/auto.master which automounts /test/1 and /test/2 automatically.

Say someone was on a system using /test/1 actively. I would want to 'fix' the system by setting up new entries in /etc/fstab for /test/1 and /test/2 and remove /test from /etc/auto.master. Then I would want to restart automount.

/test/1 would still be mounted since its in use which is good as then there is no interruption to the user. I would create /test/2 and mount a 'hard' mount on that. Since automount was restarted and no longer has an entry for /test in /etc/auto.master then /test/1 will never timeout from automount anymore.

However, the base mountpoint that automount was using is /test ... so on a reboot /test will still exist but directories /test/1 and /test/2 will no longer exist and the system will fail to mount on those /etc/fstab entries ...

What I ended up doing was:
  • mount --bind / /mnt
  • cd /mnt/test
This allows me to be 'underneath' the /test mountpoint which currently has /test/1 mounted from automount earlier.
  • mkdir 1 2
  • cd /
  • umount /mnt
Now if the system reboots /test/1 and /test/2 will exist and the mounts specified in /etc/fstab will mount correctly.

Saturday, March 13, 2010

mkinitrd: device /dev/ does not have a driver

I recently ran into an issue when trying to update the kernel on my openSUSE 11.0 system. When installing the kernel and mkinitrd ran during the kernel rpm post-scriptlet mkinitrd would fail. When I ran it on my own I would get:
Fatal storage error. device /dev/ does not have a driver
I dove into the code for mkinitrd and found 2 spots where it was getting hung up on having '/dev/' as a value in a variable called blockdev.

One was in /lib/mkinitrd/scripts/setup-block.sh and another in /lib/mkinitrd/scripts/setup-iscsi.sh.

The variable blockdev is a space delimited list of devices that these scripts loop through and execute commands against with for loops. The for loops looks like:
for bd in $blockdev; do
So each value in blockdev then get assigned temporarily to bd. I therefore added a further check right after the for bd in $blockdev; do line to check if variable bd equals exactly /dev/ and if so to skip that value:
if [ "$bd" == "/dev/" ]; then
verbose "[BLOCK] ignoring $bd (gaf)"
continue
fi
So before:
...
for bd in $blockdev; do
...
And after:
...
for bd in $blockdev; do
if [ "$bd" == "/dev/" ]; then
verbose "[BLOCK] ignoring $bd (gaf)"
continue
fi
...
I'm guessing /dev/ is being included into the blockdev variable erroneously, but I'm not gonna waste anymore time figuring that part out. :P

Hope this helps as I didn't see anyone with a solution to this issue when searching for one myself (to save time ...).

NOTE: This issue seems to be addressed in 11.2 after some update (still an issue in base 11.2). I ran into it while upgrading to 11.2 from 11.0.