Tuesday, April 21, 2009

Debian (Lenny) SAN Boot Netapp_Hook

#!/bin/sh

# The environment contains at least:
#
# CONFDIR -- usually /etc/mkinitramfs, can be set on mkinitramfs
# command line.
#
# DESTDIR -- The staging directory where we are building the image.
#
PREREQ=""

prereqs()
{
echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
prereqs
exit 0
;;
esac


# You can do anything you need to from here on.
#

# Source the optional 'hook-functions' scriptlet, if you need the
# functions defined within it. Read it to see what is available to
# you. It contains functions for copying dynamically linked program
# binaries, and kernel modules into the DESTDIR.
#
. /usr/share/initramfs-tools/hook-functions

mkdir -p $DESTDIR/opt/netapp/santools

copy_exec /opt/netapp/santools/mpath_prio_netapp /opt/netapp/santools/
copy_exec /sbin/mpath_prio_netapp /sbin/

cp /etc/multipath.conf $DESTDIR/etc/
exit 0

Debian (Lenny) SAN Boot Multipath.conf

#
# name : defaults
# desc : multipath-tools default settings
#
defaults {
#
# name : multipath_tool
# scope : multipathd
# desc : the tool in charge of configuring the multipath device maps
# default : "/sbin/multipath -v 0 -S"
#
multipath_tool "/sbin/multipath -v 0 -S"

#
# name : udev_dir
# desc : directory where udev creates its device nodes
# default : /udev
#
udev_dir /dev

#
# name : polling_interval
# scope : multipathd
# desc : interval between two path checks in seconds
# default : 5
#
polling_interval 10

#
# name : default_selector
# scope : multipath
# desc : the default path selector algorithm to use
# these algorithms are offered by the kernel multipath target
# values : "round-robin 0"
# default : "round-robin 0"
#
default_selector "round-robin 0"

#
# name : default_path_grouping_policy
# scope : multipath
# desc : the default path grouping policy to apply to unspecified
# multipaths
# default : multibus
#
default_path_grouping_policy multibus

#
# name : default_getuid_callout
# scope : multipath
# desc : the default program and args to callout to obtain a unique
# path identifier. Absolute path required
# default : /sbin/scsi_id -g -u -s
#
default_getuid_callout "/lib/udev/scsi_id -g -u --device=/dev/%n"

#
# name : default_prio_callout
# scope : multipath
# desc : the default program and args to callout to obtain a path
# priority value. The ALUA bits in SPC-3 provide an
# exploitable prio value for example
# default : /bin/false
#
default_prio_callout "/bin/false"
}

#
# name : devnode_blacklist
# scope : multipath & multipathd
# desc : list of device names to discard as not multipath candidates
# default : cciss, fd, hd, md, dm, sr, scd, st, ram, raw, loop
#
devnode_blacklist {
devnode c0d
devnode c1d
devnode c2d
devnode ub
devnode nbd
devnode fd
devnode hd
devnode md
devnode dm
devnode sr
devnode scd
devnode st
devnode ram
devnode raw
devnode loop
}

#
# name : multipaths
# scope : multipath & multipathd
# desc : list of multipaths finest-grained settings
#
multipaths {
#
# name : multipath
# scope : multipath & multipathd
# desc : container for settings that apply to one specific multipath
#
multipath {
#
# name : wwid
# scope : multipath & multipathd
# desc : index of the container
#
wwid 3600508b4000156d700012000000b0000

#
# name : alias
# scope : multipath
# desc : symbolic name for the multipath
#
alias yellow

#
# name : path_grouping_policy
# scope : multipath
# desc : path grouping policy to apply to this multipath
# values : failover, multibus, group_by_serial
# default : failover
#
path_grouping_policy multibus

#
# name : path_checker
# scope : multipathd
# desc : path checking alorithm to use to check path state
# values : readsector0, tur
# default : readsector0
#
# path_checker readsector0

#
# name : path_selector
# desc : the path selector algorithm to use for this mpath
# these algo are offered by the kernel mpath target
# values : "round-robin 0"
# default : "round-robin 0"
#
path_selector "round-robin 0"
}
multipath {
wwid 1DEC_____321816758474
alias red
}
multipath {
wwid 360a66666666666c535a4f6666666666
alias boot
}
# multipath {
# wwid ////
# alias dm2
# }
# multipath {
# wwid ////
# alias dm3
# }
}

#
# name : devices
# scope : multipath & multipathd
# desc : list of per storage controler settings
# overrides default settings (device_maps block)
# overriden by per multipath settings (multipaths block)
#
devices {
#
# name : device
# scope : multipath & multipathd
# desc : settings for this specific storage controler
#
device {
#
# name : vendor, product
# scope : multipath & multipathd
# desc : index for the block
#
vendor "COMPAQ "
product "HSV110 (C)COMPAQ"

#
# name : path_grouping_policy
# scope : multipath
# desc : path grouping policy to apply to multipath hosted
# by this storage controler
# values : failover = 1 path per priority group
# multibus = all valid paths in 1 priority
# group
# group_by_serial = 1 priority group per detected
# serial number
# default : failover
#
path_grouping_policy multibus

#
# name : getuid_callout
# scope : multipath
# desc : the program and args to callout to obtain a unique
# path identifier. Absolute path required
# default : /sbin/scsi_id -g -u -s
#
getuid_callout "/lib/udev/scsi_id -g -u --device=/dev/%n"

#
# name : prio_callout
# scope : multipath
# desc : the program and args to callout to obtain a path
# weight. Weights are summed for each path group to
# determine the next PG to use case of failure.
# default : no callout, all paths equals
#
prio_callout "/sbin/pp_balance_units %d"

#
# name : path_checker
# scope : multipathd
# desc : path checking alorithm to use to check path state
# values : readsector0, tur
# default : readsector0
#
path_checker readsector0

#
# name : path_selector
# desc : the path selector algorithm to use for this mpath
# these algo are offered by the kernel mpath target
# values : "round-robin 0"
# default : "round-robin 0"
#
path_selector "round-robin 0"
}

device {
vendor "NETAPP"
product "LUN"
path_grouping_policy group_by_prio
getuid_callout "/lib/udev/scsi_id -g -u --device=/dev/%n"
prio_callout "/opt/netapp/santools/mpath_prio_netapp /dev/%n"
features "1 queue_if_no_path"
path_checker tur
failback immediate
}
}

Monday, April 20, 2009

Debian (Lenny) SAN Boot using Multipath-tools

I was asked to look at setting up an install of Debian's Lenny release to boot from our Netapp FC SAN. I had some difficulty initially, partially due to a few changes from Etch, partially due to some changes in Netapp's FC host utilities for Linux. Hopefully this will help someone else avoid some stress.

Here's the relevant details on the hardware:

Netapp FAS3020c(lustered) running 7.2.5.1
Dual Homed FC Fabric (Brocade)
Qlogic 2300 series HBA
IBM HS20 series blade
5GB LUN presented to host on 4 paths

Firmware on the server hardware has been flashed up to current rev as of 4/18/2009.

So I pop the disc in and off we go...

Proceed through the installer up to the time zone information (just prior to disk detection), opting not to install the HBA firmware from removable media. Prior to disk detection, press ALT+F2 to switch to console.

At the console, download the udeb for your HBA and reload the qlogic module.

wget http://ftp.us.debian.org/debian/pool/non-free/f/firmware-nonfree/firmware-qlogic-di_0.9_all.udeb
udpkg -i firmware-qlogic-di_0.9_all.udeb
modprobe -r qla2xxx
modprobe qla2xxx
Press ALT+F1 to return to the installer and proceed to disk detection. Continue through the installer however you like up to the point where you would normally reboot into the installed OS, and drop back into the command prompt (ALT+F2).

Now it's time to install the firmware for your HBA into initramfs:

wget http://ftp.us.debian.org/debian/pool/non-free/f/firmware-nonfree/firmware-qlogic_0.16_all.deb
cp firmware-qlogic_0.16_all.deb target/home
chroot target
cd home
chmod 755 firmware-qlogic_0.16_all.deb
dpkg -i firmware-qlogic_0.16_all.deb
update-initramfs -uv

ALT+F1 to drop back into the installer, and reboot into your OS on a single path.

Update your package list and install some necessary packages (and maybe one or two unnecessary ones, vim and ssh being for my own convenience):

apt-get update
apt-get install multipath-tools multipath-tools-initramfs ssh vim lsb
Create an /etc/multipath.conf file (http://caskethopper.blogspot.com/2009/04/debian-lenny-san-boot-multipathconf.html ), an /etc/initramfs-tools/hooks/netapp_hook file (http://caskethopper.blogspot.com/2009/04/debian-lenny-san-boot-netapphook.html), and copy the netapp linux host utilities to /usr/local/src. CD to /usr/local/src and install the host utilities:
cd /usr/local/src
tar xvzf netapp_linux_host_utilities_4_2.tar.gz
cd netapp_linux_host_utils_4_2
./install
Then make /etc/initramfs-tools/hooks/netapp_hook executable:
chmod 755 /etc/initramfs-tools/hooks/netapp_hook
Copy the mpath_prio_netapp file from /sbin to /opt/netapp/santools (or edit every location that points to that location and change it to /sbin, or create a sym link, whatever floats your boat). I'm guessing that it's supposed to do this for you, but it doesn't seem to happen for me. Also, apparently the tarball extracts a number of files with unknown uids, so set root as owner of any unowned files:
find / -nouser 2>/dev/null | xargs chown root:root
Next you need to find the wwid of your scsi disk, and this is where they try to trip you up if you're coming from an etch boot from san environment. In previous versions, the scsi_id command was located in /sbin, but now it's in /lib/udev. Anyway, locate your scsi wwid with the command:
/lib/udev/scsi_id -g -p 0x83 -s /block/{whatever your disk id is}
Write this down somewhere, because you're going to need it.

Edit the multipath.conf file to create a friendly alias for your disk's wwid. You can see in the multipath.conf file where I created the device "boot" as an alias for my disk.

Next, edit /etc/initramfs-tools/modules to include the following modules:
  • firmware_class
  • dm_mod
  • dm_multipath
  • dm_round_robin
Another issue I ran into, the netapp host utilities appear to be hard-coded to look for libdevmapper.so, and since the version Lenny installs with creates /lib/libdevmapper.so.1.02.1 I wasn't sure what to do. I couldn't find the config for the netapp host utilites to point to the correct file, so I just created a sym link to the correct file. Please comment if there is a better way to fix this.
ln -s /lib/libdevmapper.so.1.02.1 /lib/libdevmapper.so
Edit /etc/fstab and /boot/grub/menu.lst to point to the new, multipathed disk locations. The format of the name will change from /dev/sd# to /dev/mapper/{alias}-part#, so for example, /dev/sda1 will become /dev/mapper/boot-part1.

Update your initramfs:
update-initramfs -uv
Reboot, ????, and profit.

Thanks to the boss man for the original Etch boot from SAN docs...