iscsi: add support for multiple netroot=iscsi:
authorHarald Hoyer <harald@redhat.com>
Wed, 9 Jun 2010 14:41:10 +0000 (16:41 +0200)
committerHarald Hoyer <harald@redhat.com>
Wed, 9 Jun 2010 14:46:33 +0000 (16:46 +0200)
The whole netdisk concept should be reviewed though!

dracut.8
modules.d/95iscsi/iscsiroot
test/TEST-30-ISCSI/create-root.sh
test/TEST-30-ISCSI/targets
test/TEST-30-ISCSI/test.sh

index 0946b99..4050541 100644 (file)
--- a/dracut.8
+++ b/dracut.8
@@ -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
index 6d0dde6..23e26a6 100755 (executable)
@@ -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)
 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*
index fd41347..2b7cac1 100755 (executable)
@@ -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
 
index e3c7114..6a6872e 100644 (file)
 
 # 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
index 4dbd6d6..637f264 100755 (executable)
@@ -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 \
@@ -37,9 +38,19 @@ run_client() {
        -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 \
+       -kernel /boot/vmlinuz-$KVERSION \
        -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() {
 
     # 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() {
        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() {
     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