Browse Source

iscsi: add support for multiple netroot=iscsi:

The whole netdisk concept should be reviewed though!
master
Harald Hoyer 15 years ago
parent
commit
169f167151
  1. 1
      dracut.8
  2. 176
      modules.d/95iscsi/iscsiroot
  3. 12
      test/TEST-30-ISCSI/create-root.sh
  4. 4
      test/TEST-30-ISCSI/targets
  5. 19
      test/TEST-30-ISCSI/test.sh

1
dracut.8

@ -332,7 +332,6 @@ e.g. root=iscsi:192.168.50.1::::iqn.2009-06.dracut:target0 @@ -332,7 +332,6 @@ e.g. root=iscsi:192.168.50.1::::iqn.2009-06.dracut:target0
.BR root= ??? " netroot=" "\%iscsi:[username:password[:reverse:password]@]\:[<servername>]\::[<protocol>]\::[<port>]\::[<LUN>]\::<targetname> ..."
.ad
multiple netroot options allow setting up multiple iscsi disks
.B Not yet implemented!
e.g.
root=UUID=12424547
netroot=iscsi:192.168.50.1::::iqn.2009-06.dracut:target0

176
modules.d/95iscsi/iscsiroot

@ -33,7 +33,7 @@ iroot=${iroot#iscsi:} @@ -33,7 +33,7 @@ iroot=${iroot#iscsi:}

# XXX modprobe crc32c should go in the cmdline parser, but I haven't yet
# figured out a way how to check whether this is built-in or not
modprobe crc32c
modprobe crc32c 2>/dev/null


[ -e /tmp/root.info ] && . /tmp/root.info
@ -67,112 +67,126 @@ arg=$(getarg iscsi_in_username) @@ -67,112 +67,126 @@ arg=$(getarg iscsi_in_username)
arg=$(getarg iscsi_in_password)
[ -n "$arg" ] && iscsi_in_password=$arg

# override conf/commandline options by dhcp root_path
# FIXME this assumes that all values have been provided
OLDIFS="$IFS"
IFS=@
set $iroot
if [ $# -gt 1 ]; then
authinfo=$1; shift
iroot=$*
handle_netroot()
{
iroot=$1
# override conf/commandline options by dhcp root_path
# FIXME this assumes that all values have been provided
OLDIFS="$IFS"
IFS=@
set $iroot
if [ $# -gt 1 ]; then
authinfo=$1; shift
iroot=$*
# allow empty authinfo to allow having an @ in iscsi_target_name like this:
# netroot=iscsi:@192.168.1.100::3260::iqn.2009-01.com.example:testdi@sk
if [ -n "$authinfo" ]; then
IFS=:
set $authinfo
iscsi_username=$1
iscsi_password=$2
if [ $# -gt 2 ]; then
iscsi_in_username=$3
iscsi_in_password=$4
fi
fi
fi

IFS="$OLDIFS"

local v=${iroot}:
local i
set --
while [ -n "$v" ]; do
if [ "${v#\[*:*:*\]:}" != "$v" ]; then
if [ -n "$authinfo" ]; then
IFS=:
set $authinfo
iscsi_username=$1
iscsi_password=$2
if [ $# -gt 2 ]; then
iscsi_in_username=$3
iscsi_in_password=$4
fi
fi
fi

IFS="$OLDIFS"

local v=${iroot}:
local i
set --
while [ -n "$v" ]; do
if [ "${v#\[*:*:*\]:}" != "$v" ]; then
# handle IPv6 address
i="${v%%\]:*}"
i="${i##\[}"
set -- "$@" "$i"
v=${v#\[$i\]:}
else
set -- "$@" "${v%%:*}"
v=${v#*:}
fi
done
iscsi_target_ip=$1; shift
iscsi_protocol=$1; shift # ignored
iscsi_target_port=$1; shift
iscsi_lun=$1; shift
IFS=:
iscsi_target_name=$*
IFS="$OLDIFS"
i="${v%%\]:*}"
i="${i##\[}"
set -- "$@" "$i"
v=${v#\[$i\]:}
else
set -- "$@" "${v%%:*}"
v=${v#*:}
fi
done
iscsi_target_ip=$1; shift
iscsi_protocol=$1; shift # ignored
iscsi_target_port=$1; shift
iscsi_lun=$1; shift
IFS=:
iscsi_target_name=$*
IFS="$OLDIFS"
# XXX is this needed?
getarg ro && iscsirw=ro
getarg rw && iscsirw=rw
fsopts=${fsopts+$fsopts,}${iscsirw}
getarg ro && iscsirw=ro
getarg rw && iscsirw=rw
fsopts=${fsopts+$fsopts,}${iscsirw}

if [ -z $iscsi_initiator ]; then
if [ -z $iscsi_initiator ]; then
# XXX Where are these from?
[ -f /etc/initiatorname.iscsi ] && . /etc/initiatorname.iscsi
[ -f /etc/iscsi/initiatorname.iscsi ] && . /etc/iscsi/initiatorname.iscsi
iscsi_initiator=$InitiatorName
[ -f /etc/initiatorname.iscsi ] && . /etc/initiatorname.iscsi
[ -f /etc/iscsi/initiatorname.iscsi ] && . /etc/iscsi/initiatorname.iscsi
iscsi_initiator=$InitiatorName

# XXX rfc3720 says 'SCSI Initiator Name: The iSCSI Initiator Name specifies
# the worldwide unique name of the initiator.' Could we use hostname/ip
# if missing?
fi
fi

if [ -z $iscsi_target_port ]; then
iscsi_target_port=3260
fi
if [ -z $iscsi_target_port ]; then
iscsi_target_port=3260
fi

if [ -z $iscsi_target_group ]; then
iscsi_target_group=1
fi
if [ -z $iscsi_target_group ]; then
iscsi_target_group=1
fi

if [ -z $iscsi_initiator ]; then
if [ -z $iscsi_initiator ]; then
# XXX is this correct?
iscsi_initiator=$(iscsi-iname)
fi
iscsi_initiator=$(iscsi-iname)
fi

if [ -z $iscsi_lun ]; then
iscsi_lun=0
fi
if [ -z $iscsi_lun ]; then
iscsi_lun=0
fi

echo "InitiatorName='$iscsi_initiator'" > /dev/.initiatorname.iscsi
echo "InitiatorName='$iscsi_initiator'" > /dev/.initiatorname.iscsi

# FIXME $iscsi_protocol??

if [ -n "${root%%block:*}" ]; then
if [ -n "${root%%block:*}" ]; then
# if root is not specified try to mount the whole iSCSI LUN
printf 'SYMLINK=="disk/by-path/*-iscsi-*-%s", SYMLINK+="root"\n' $iscsi_lun >> /etc/udev/rules.d/99-iscsi-root.rules
fi
printf 'SYMLINK=="disk/by-path/*-iscsi-*-%s", SYMLINK+="root"\n' $iscsi_lun >> /etc/udev/rules.d/99-iscsi-root.rules
fi

# inject new exit_if_exists
echo 'settle_exit_if_exists="--exit-if-exists=/dev/root"; rm "$job"' > /initqueue/iscsi-settle.sh
# inject new exit_if_exists
echo 'settle_exit_if_exists="--exit-if-exists=/dev/root"; rm "$job"' > /initqueue/iscsi-settle.sh

# force udevsettle to break
> /initqueue/work
# force udevsettle to break
> /initqueue/work

iscsistart -i $iscsi_initiator -t $iscsi_target_name \
-g $iscsi_target_group -a $iscsi_target_ip \
-p $iscsi_target_port \
${iscsi_username+-u $iscsi_username} \
${iscsi_password+-w $iscsi_password} \
${iscsi_in_username+-U $iscsi_in_username} \
${iscsi_in_password+-W $iscsi_in_password} || exit 1
iscsistart -i $iscsi_initiator -t $iscsi_target_name \
-g $iscsi_target_group -a $iscsi_target_ip \
-p $iscsi_target_port \
${iscsi_username+-u $iscsi_username} \
${iscsi_password+-w $iscsi_password} \
${iscsi_in_username+-U $iscsi_in_username} \
${iscsi_in_password+-W $iscsi_in_password} || :

# install mount script
if [ -n "${root%%block:*}" ]; then
if [ -n "${root%%block:*}" ]; then
# if root is not specified try to mount the whole iSCSI LUN
echo "iscsi_lun=$iscsi_lun . /bin/mount-lun.sh " > /mount/01-$$-iscsi.sh
echo "iscsi_lun=$iscsi_lun . /bin/mount-lun.sh " > /mount/01-$$-iscsi.sh
fi
}

# loop over all netroot parameter
if getarg netroot; then
for nroot in $(getargs netroot); do
[ "${netroot%%:*}" = "iscsi" ] || continue
handle_netroot ${nroot##iscsi:}
done
else
handle_netroot $iroot
fi

# now we have a root filesystem somewhere in /dev/sda*

12
test/TEST-30-ISCSI/create-root.sh

@ -3,12 +3,24 @@ @@ -3,12 +3,24 @@
for x in 64-lvm.rules 70-mdadm.rules 99-mount-rules; do
> "/etc/udev/rules.d/$x"
done
rm /etc/lvm/lvm.conf
udevadm control --reload-rules
mke2fs -F /dev/sda && \
mkdir -p /sysroot && \
mount /dev/sda /sysroot && \
cp -a -t /sysroot /source/* && \
umount /sysroot && \
mdadm --create /dev/md0 --run --auto=yes --level=stripe --raid-devices=2 /dev/sdc /dev/sdd && \
mdadm -W /dev/md0 || : && \
lvm pvcreate -ff -y /dev/md0 && \
lvm vgcreate dracut /dev/md0 && \
lvm lvcreate -l 100%FREE -n root dracut && \
lvm vgchange -ay && \
mke2fs -L sysroot /dev/dracut/root && \
mount /dev/dracut/root /sysroot && \
cp -a -t /sysroot /source/* && \
umount /sysroot && \
lvm lvchange -a n /dev/dracut/root && \
echo "dracut-root-block-created" >/dev/sdb
poweroff -f


4
test/TEST-30-ISCSI/targets

@ -16,6 +16,10 @@ @@ -16,6 +16,10 @@

# extents file start length
extent0 /dev/sdb 0 20971520
extent1 /dev/sdc 0 20971520
extent2 /dev/sdd 0 20971520

# target flags storage netmask
target0 rw extent0 192.168.50.0/24
target1 rw extent1 192.168.50.0/24
target2 rw extent2 192.168.50.0/24

19
test/TEST-30-ISCSI/test.sh

@ -10,6 +10,7 @@ run_server() { @@ -10,6 +10,7 @@ run_server() {
echo "iSCSI TEST SETUP: Starting DHCP/iSCSI server"

$testdir/run-qemu -hda server.ext2 -hdb root.ext2 -m 256M -nographic \
-hdc iscsidisk2.img -hdd iscsidisk3.img \
-net nic,macaddr=52:54:00:12:34:56,model=e1000 \
-net socket,listen=127.0.0.1:12345 \
-serial udp:127.0.0.1:9999 \
@ -33,6 +34,15 @@ run_client() { @@ -33,6 +34,15 @@ run_client() {
return 1
fi

$testdir/run-qemu -hda client.img -m 256M -nographic \
-net nic,macaddr=52:54:00:12:34:00,model=e1000 \
-net socket,connect=127.0.0.1:12345 \
-kernel /boot/vmlinuz-$KVERSION \
-append "root=LABEL=sysroot ip=192.168.50.101::192.168.50.1:255.255.255.0:iscsi-1:eth0:off netroot=iscsi:192.168.50.1::::iqn.2009-06.dracut:target1 netroot=iscsi:192.168.50.1::::iqn.2009-06.dracut:target2 rw quiet rd_retry=5 rdinitdebug rdinfo rdnetdebug console=ttyS0,115200n81 selinux=0 $DEBUGFAIL" \
-initrd initramfs.testing
grep -m 1 -q iscsi-OK client.img || return 1


$testdir/run-qemu -hda client.img -m 256M -nographic \
-net nic,macaddr=52:54:00:12:34:00,model=e1000 \
-net socket,connect=127.0.0.1:12345 \
@ -40,6 +50,7 @@ run_client() { @@ -40,6 +50,7 @@ run_client() {
-append "root=dhcp rw quiet rd_retry=5 rdinitdebug rdinfo rdnetdebug console=ttyS0,115200n81 selinux=0 $DEBUGFAIL" \
-initrd initramfs.testing
grep -m 1 -q iscsi-OK client.img || return 1

}

test_run() {
@ -64,6 +75,8 @@ test_setup() { @@ -64,6 +75,8 @@ test_setup() {

# Create the blank file to use as a root filesystem
dd if=/dev/zero of=root.ext2 bs=1M count=20
dd if=/dev/zero of=iscsidisk2.img bs=1M count=20
dd if=/dev/zero of=iscsidisk3.img bs=1M count=20

kernel=$KVERSION
# Create what will eventually be our root filesystem onto an overlay
@ -104,7 +117,9 @@ test_setup() { @@ -104,7 +117,9 @@ test_setup() {
return 1
fi
# Invoke KVM and/or QEMU to actually create the target filesystem.
$testdir/run-qemu -hda root.ext2 -hdb client.img -m 256M -nographic -net none \
$testdir/run-qemu -hda root.ext2 -hdb client.img \
-hdc iscsidisk2.img -hdd iscsidisk3.img \
-m 256M -nographic -net none \
-kernel "/boot/vmlinuz-$kernel" \
-append "root=/dev/dracut/root rw rootfstype=ext2 quiet console=ttyS0,115200n81 selinux=0" \
-initrd initramfs.makeroot || return 1
@ -177,7 +192,7 @@ test_cleanup() { @@ -177,7 +192,7 @@ test_cleanup() {
fi
rm -rf mnt overlay
rm -f client.ext2 server.ext2 client.img initramfs.server initramfs.testing
rm -f initramfs.makeroot root.ext2
rm -f initramfs.makeroot root.ext2 iscsidisk2.img iscsidisk3.img
}

. $testdir/test-functions

Loading…
Cancel
Save