This is an old revision of the document!


Getting iSCSI booting to work with Ubuntu Lucid Lynx 10.04

(Including logon and ibft support!)

For this example, I will use these values:

  • iSCSI Qualified Name: iqn.2010-09.org.test:diskimg
  • Server ip: 192.168.1.1
  • Client ip: 192.168.1.2
  • iSCSI username: user
  • iSCSI password: password
  • Client disk image: /mnt/disk-images/disk.img

Client side setup (initiator):

On the client side, install a standard Ubuntu Desktop on a physical or virtual machine. If you use a virtual machine, make the sure disk image is in 'raw' format, meaning no headers or such on the image. If it is a valid raw image, you should be able to see the partition table with, for example “fdisk -l disk.img” or even the “disktype” command, like so:

$ disktype disk.img 

--- disk.img
Regular file, size 6 GiB (6442450944 bytes)
DOS/MBR partition map
Partition 1: 5.858 GiB (6290407424 bytes, 12285952 sectors from 2048, bootable)
  Type 0x83 (Linux)
  Ext3 file system
    UUID 745D45C4-38FA-4B7C-85A3-71D37AE23AF3 (DCE, v4)
    Volume size 5.858 GiB (6290407424 bytes, 1535744 blocks of 4 KiB)
Partition 2: 144 MiB (150994944 bytes, 294912 sectors from 12288000)
  Type 0x82 (Linux swap / Solaris)
  Linux swap, version 2, subversion 1, 4 KiB pages, little-endian
    Swap size 144.0 MiB (150986752 bytes, 36862 pages of 4 KiB)

Use the following steps to make the Ubuntu client iSCSI capable:

Paste the following code into a new file called /etc/initramfs-tools/hooks/iscsi:
#!/bin/sh
PREREQ=""
prereqs()
{
     echo "$PREREQ"
}

case $1 in
prereqs)
     prereqs
     exit 0
     ;;
esac

# Begin real processing below this line
if [ ! -x /sbin/iscsistart ]; then
   exit 0
fi
. /usr/share/initramfs-tools/hook-functions
copy_exec /sbin/iscsistart /sbin
chmod -x /sbin/iscsid   # Disable iscsid since we are using iscsistart and iscsid will interfere by re-discovering
for x in scsi_transport_iscsi libiscsi libiscsi_tcp iscsi_tcp \
   crc32c iscsi_ibft; do
   force_load ${x}
done
Paste the following code into a new file called /etc/initramfs-tools/scripts/local-top/iscsi:
#!/bin/sh

# Do the following so we do not get errors when doing 'update-initramfs -u'
if [ ! "$BOOT" = "local" ]; then
   exit 0
fi

# Check if the target exists then start iscsi
if [ -e /sys/firmware/ibft/target0/target-name ]; then
   udevadm settle --timeout=30    # wait for netcard
   #ip link set eth0 mtu 2500     # Optional: increase mtu for performance
   ip link set eth0 up            # bring the network interface up
   sleep 5                        # wait for the ethernet interface to come up
   ipconfig -t 10 -c dhcp -d eth0 # get an IP
   #iscsistart -b                 # This should get the ibft parameters but it does not work for me
                                  # Lets do the following instead
   iscsistart \
    -i `cat /sys/firmware/ibft/initiator/initiator-name` \
    -t `cat /sys/firmware/ibft/target0/target-name` \
    -a `cat /sys/firmware/ibft/target0/ip-addr` \
    -u `cat /sys/firmware/ibft/target0/chap-name` \
    -w `cat /sys/firmware/ibft/target0/chap-secret` \
    -g 1
fi

Make sure that eth0 is set to manual in /etc/network/interfaces so that Network Manager does not try to reconfigure the interface:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet manual

Then do these commands at the terminal:

sudo -s                                               # Become root, if it asks for password, use the users password
chmod +x /etc/initramfs-tools/hooks/iscsi             # Make your hook script executable
chmod +x /etc/initramfs-tools/scripts/local-top/iscsi # Make your script executable
apt-get install open-iscsi open-iscsi-utils           # Make sure you have the iscsi tools installed
update-initramfs -u                                   # Update initramfs with your changes, 
                                                      # the changes will also take effect even with upgrades
Do the following so that your eth0 interface has the same name even if the image is booted on different machines
sudo -s                                                   # Change to root access
rm /etc/udev/rules.d/70-persistent-net.rules              # Get rid of this rule so that your current eth0 interface doesn't get changed
rm /lib/udev/rules.d/75-persistent-net-generator.rules    # This re-creates the above, so get rid of it too

Note: I don't know if the above steps are the best way to make eth0 name static, but this is what works for me.

You are now finished with editing the client. Shutdown the client now.

Last step: Transfer the image to the server

You could just copy the image as is, but it is even smarter to make a sparse file. That way only actual data is copied and not the empty sectors. You can do this under linux with the cp command:

cp --sparse=always disk.img /media/server-data/disk-images/disk.img

If you installed to a physical machine, boot up the machine with a live linux cd, become root and do this command:

cp --sparse=always /dev/sda /media/server-data/disk-images/disk.img

Server side setup (target):

I am assuming that you are using either Ubuntu or Debian linux on the server. Make sure you have a dhcp and a tftp server installed and that you have followed the directions for setting up gpxe on the dhcp server from etherboot.org. Install the “iscsitarget” package using this command:

sudo apt-get install iscsitarget

Assuming /mnt/disk-images/disk.img is your client image, create the /etc/ietf.conf file with the following contents:

Target iqn.2010-09.org.test:diskimg
        IncomingUser user password
        OutgoingUser
        Lun 0 Path=/mnt/disk-images/disk.img,IOMode=wb,Type=fileio

Make sure iscsitarget can start at boot by using this value in /etc/default/iscsitarget

ISCSITARGET_ENABLE=true

Make the gpxe script /tftpboot/iscsi.gpxe with these contents:

dhcp net0
set username user
set password password
sanboot iscsi:192.168.1.1::::iqn.2010-09.org.test:diskimg

Edit your dhcpd.conf file and make sure the following is in your gpxe section of the config file:

filename=iscsi.gpxe

That's it! Start your server by running “sudo /etc/init.d/iscsitarget restart” and boot your pxe client and see what happens.

BTRFS workaround

In order to work around the kernel oops when iscsi image files are residing on a btrfs file system, change the /etc/ietf.conf file as follows:

Target iqn.2010-09.org.test:diskimg
        IncomingUser user password
        OutgoingUser
        Lun 0 Path=/dev/loop0,IOMode=wb,Type=blockio

…and create a loop device that points to the image:

losetup /dev/loop0 /mnt/disk-images/disk.img

Random Notes

  • If you don't install any proprietary video drivers, then what you got here is an image that will boot from either iSCSI, USB, or any internal/external disk on any machine.
  • Since Ubuntu is Debian based, these steps should work with Debian too but I haven't tried it myself
  • You cannot create sparse images if you copy to a windows or samba network share, use nfs/ssh/nc (netcat) instead. Here is an example with nc (netcat):

Client side:

cat /dev/sda | nc -l -p 1234

Server side:

nc <client-ip> 1234 | cp --sparse=always /dev/stdin disk.img

Quinn Plattel 2010/09/22 10:09


QR Code
QR Code sanboot:ubuntu_iscsi2 (generated for current page)