File libguestfs.mkinitrd.1220.patch of Package libguestfs.215

---
 mkinitrd/scripts/setup-ibft.sh       |    2 
 mkinitrd/scripts/setup-network.sh    |   11 ++-
 mkinitrd/scripts/setup-prepare.sh    |  126 +++++++++++++++++++++--------------
 mkinitrd/scripts/setup-progs.sh      |   17 ----
 mkinitrd/scripts/setup-scsi_dh.sh    |    2 
 mkinitrd/scripts/setup-sharedlibs.sh |   60 +++++++++-------
 6 files changed, 126 insertions(+), 92 deletions(-)

Index: 1220/mkinitrd/scripts/setup-ibft.sh
===================================================================
--- 1220.orig/mkinitrd/scripts/setup-ibft.sh
+++ 1220/mkinitrd/scripts/setup-ibft.sh
@@ -21,22 +21,22 @@ ibft_set_iface() {
 	interface=$iface
 	drvlink=$(get_network_module $interface)
 	if [ ! "$nettype" -a -e $ibft_nic/dhcp ]; then
 	    nettype=dhcp
 	    read ibft_dhcp < $ibft_nic/dhcp
 	    [ "$ibft_dhcp" = "0.0.0.0" ] && nettype=static
 	else
 	    nettype=static
 	fi
     fi
 }
 
 ibft_nic=/sys/firmware/ibft/ethernet0
-ibft_hostname=$(hostname)
+ibft_hostname=localhost
 
 if [ "$root_iscsi" = 1 -a -d $ibft_nic ]; then
     ibft_available=1
     ibft_set_iface
 fi
 save_var ibft_available
 save_var ibft_hostname
 save_var ibft_nic
Index: 1220/mkinitrd/scripts/setup-network.sh
===================================================================
--- 1220.orig/mkinitrd/scripts/setup-network.sh
+++ 1220/mkinitrd/scripts/setup-network.sh
@@ -278,27 +278,36 @@ if [ "$nettype" = "ifup" ] ; then
 	    verbose "[NETWORK]\tifup: $interface"
 	fi
     done
     interface=
 fi
 
 # Copy the /etc/resolv.conf when the IP is static
 if test -n "$static_interfaces"; then
     verbose "[NETWORK]\tUsing /etc/resolv.conf from the system in the initrd"
     cp /etc/resolv.conf $tmp_mnt/etc
 fi
 
 # Copy netcfg files (bnc#468090, bnc#714945)
-cp /etc/{hosts,protocols,services,netconfig} $tmp_mnt/etc
+cp /etc/{protocols,services,netconfig} $tmp_mnt/etc
+cat > $tmp_mnt/etc/hosts <<_EOH_
+127.0.0.1 localhost
+::1       localhost ipv6-localhost ipv6-loopback
+fe00::0   ipv6-localnet
+ff00::0   ipv6-mcastprefix
+ff02::1   ipv6-allnodes
+ff02::2   ipv6-allrouters
+ff02::3   ipv6-allhosts
+_EOH_
 
 # Get static IP configuration if requested
 for iface in $static_interfaces; do
     static_ips="$static_ips $(get_ip_config $iface)"
 done
 
 mkdir -p $tmp_mnt/var/lib/dhcpcd
 mkdir -p $tmp_mnt/var/run
 
 cp_bin /lib/mkinitrd/bin/ipconfig.sh $tmp_mnt/bin/ipconfig
 if [ -f /etc/udev/rules.d/70-persistent-net.rules ] ; then
     cp /etc/udev/rules.d/70-persistent-net.rules $tmp_mnt/etc/udev/rules.d
 fi
Index: 1220/mkinitrd/scripts/setup-prepare.sh
===================================================================
--- 1220.orig/mkinitrd/scripts/setup-prepare.sh
+++ 1220/mkinitrd/scripts/setup-prepare.sh
@@ -13,77 +13,103 @@
 #%param_R: "Print release (version)."
 #%param_L: "Disable logging."
 #%param_h: "This help screen."
 #
 ###### Additional options
 ##
 ## Script inclusion may be overriden by
 ##      1) creating a monster-initrd
 ##      2) including the wanted module in the configuration option ADDITIONAL_FEATURES in /etc/sysconfig/initrd
 ##      3) definition using the -f command line switch
 ##
 
 # Install a binary file
-cp_link() {
-    # Copy the target of the given link $1 to the destination $2
-    # spaces and special characters in file names will break things
-    if [ -h "$1" ]; then
-        lnkTarget=$(readlink $1)
-        if [ -e $lnkTarget ];then
-	    cp -a $lnkTarget $2/$lnkTarget
-        else
-            # This link points to something in the same directory
-            lnkSrc="$1"
-            # Get the base bath of the link origin
-            lnkSrcBase=${lnkSrc%/*}
-            cp -a $lnkSrcBase/$lnkTarget $2/$lnkSrcBase/$lnkTarget
-        fi
-	return 1
-    fi
-    return 0
-}
-
+# cp_bin file target_filename
+# cp_bin file target_directory
+# cp_bin file file target_directory
+# file is either a regular file or a symlink. symlinks and all paths they point to will be copied
+# the "root" of target is $tmp_mnt, which is required to copy symlinks properly
 cp_bin() {
-    cp -a "$@" \
-    || exit_code=1
-
-    if [ -h "$1" ]; then
-        lnkTarget=$1
-	# Determine the base bath of the target
-        targetPath="$2"
-        targetBase=${targetPath%$1*}
-        while [ 1 ]; do
-            cp_link $lnkTarget $targetBase
-            lnkCopied=$?
-            if [ $lnkCopied = 0 ]; then
-               if [ -e $lnkTarget ]; then
-                   initrd_bins[${#initrd_bins[@]}]=$lnkTarget
-               fi
-	       break
-            fi
-        done 
-    else
-        # Remember the binaries installed. We need the list for checking
-        # for dynamic libraries.
-        while [ $# -gt 1 ]; do
-            initrd_bins[${#initrd_bins[@]}]=$1
-            shift
-        done
-        # file may print '^setuid ELF ...'
-        # suid mount will fail if mkinitrd was called as user
-        if [ -d "$1" -o -f "$1" ]; then
-            find "$1" -type f -print0 | xargs -0 chmod 0755
-        fi
-    fi
+	local -a files
+	local target
+	local target_dirname
+	local file
+
+	# need at least two parameters, source and destination
+	if test $# -lt 2
+	then
+		return 0
+	fi
+	# store source filenames
+	until test $# -eq 1
+	do
+		files=( ${files[@]} $1 )
+		shift
+	done
+	# store target, either file or directory
+	target=$1
+	# if more than two parameters, last entry must be a directory
+	if test ${#files[@]} -gt 1
+	then
+		if ! test -d ${target}
+		then
+			return 0
+		fi
+		target_dirname=${target}
+	else
+		# simplify symlink resolving for sinlge filename
+		target_dirname=${target%/*}
+	fi
+
+	for file in ${files[@]}
+	do
+		local src dst
+		src=${file}
+		dst=${target}
+		# copy requested soure file as is to requested destination
+		cp -a -v --remove-destination ${src} ${dst}
+		# copy symlinks recursivly
+		while [ 1 ]
+		do
+			local tmp_src
+			if test -L ${src}
+			then
+				tmp_src=$(readlink ${src})
+				if test "${tmp_src:0:1}" = "/"
+				then
+					src=${tmp_src}
+				else
+					# relative symlink
+					src=${src%/*}/${tmp_src}
+				fi
+				cp -a -v --remove-destination --parents ${src} $tmp_mnt
+				# if link target exists, proceed to next symlink target
+				if test -e "${src}"
+				then
+					continue
+				fi
+			fi
+			# exit loop in case of dead symlink or if target of symlink was reached
+			break
+		done
+		# if source file exists, add it to list of binaries
+		if test -e "${src}"
+		then
+			# file may print '^setuid ELF ...'
+			# suid mount will fail if mkinitrd was called as user
+			chmod -v 0755 $tmp_mnt/${src}
+			initrd_bins[${#initrd_bins[@]}]=${src}
+		fi
+	done
 }
 
 # check if we should use script or feature $1
 use_script() {
     local condition feature script file
 
     # always use when creating monster initrd
     [ "$create_monster_initrd" ] && return 0
 
     # Normalize to feature name
     feature="${1##*/}"
     feature="${feature#*-}"
     feature="${feature%.sh}"
Index: 1220/mkinitrd/scripts/setup-progs.sh
===================================================================
--- 1220.orig/mkinitrd/scripts/setup-progs.sh
+++ 1220/mkinitrd/scripts/setup-progs.sh
@@ -24,48 +24,37 @@ for script in $INITRD_PATH/boot/*.sh; do
         condition="$(sed -rn 's/^#[[:blank:]]*%if:[[:blank:]]*(.*)$/if [ \1 ]; then/p' < "$script")"
           echo "$condition" >> run_all.sh
           # -- remember dependent modules
           sed -rn 's/^#[[:blank:]]*%modules:[[:blank:]]*(.*)$/modules="\1"/p' < $script >> run_all.sh
           echo "[ \"\$debug\" ] && echo running $file
 source boot/$file
 [ \"\$modules\" ] && load_modules" >> run_all.sh
         [ "$condition" ] && echo "fi" >> run_all.sh
         # and all programs it needs
         for files in $(sed -rn 's/^#[[:blank:]]*%programs:[[:blank:]]*(.*)$/\1/p' < "$script"); do
             for file in $(eval echo $files); do
                 if [ "${file:0:17}" = "/lib/mkinitrd/bin" ]; then
                         SOURCE=$file
-                        DEST="./bin/"
+                        DEST="${tmp_mnt}/bin/"
                 elif [ "${file:0:1}" = "/" ]; then # absolute path files have to stay alive
                         SOURCE=$file
                         [ ! -e $file -a -e /usr$file ] && SOURCE="/usr$file"
-                        DEST=".$file"
+                        DEST="${tmp_mnt}$SOURCE"
                 else
                         case "$(type -t "$file")" in
                         builtin) continue
                         esac
                         SOURCE=$(type -p "$file")
-                        DEST="./bin/"
+                        DEST="${tmp_mnt}$SOURCE"
                 fi
 
                 cp_bin "$SOURCE" "$DEST"
-
-                # if we're given a symlink, always copy the linked file too
-                if [ -L "$SOURCE" ]; then
-                    LINK=$(readlink -e "$SOURCE")
-                    if [ -e "$LINK" ]; then
-                        mkdir -p .$(dirname "$LINK")
-                        cp_bin "$LINK" ."$LINK"
-                    else
-                        echo 2>&1 "WARNING: $LINK is a dangling symlink"
-                    fi
-                fi
             done
         done
     fi
 done
 
 echo -ne "Features:       "
 echo $features
 
 [ -e "bin/sh" ] || ln -s /bin/bash bin/sh
 
Index: 1220/mkinitrd/scripts/setup-scsi_dh.sh
===================================================================
--- 1220.orig/mkinitrd/scripts/setup-scsi_dh.sh
+++ 1220/mkinitrd/scripts/setup-scsi_dh.sh
@@ -1,13 +1,13 @@
 #!/bin/bash
 #
 #%stage: device
 #
 # Include all scsi_dh_* modules and load them on boot (bnc#727428 et al)
 
 scsi_dh_modules=
-for i in $(find $root_dir/lib/modules/$kernel_version/kernel/drivers/scsi/device_handler -name "scsi[-_]dh[_-]*.ko"); do
+for i in $(find $root_dir/lib/modules/$kernel_version/kernel/drivers/scsi/device_handler -name "scsi[-_]dh[_-]*.ko"| sort); do
 	i=${i%.ko}
 	scsi_dh_modules="$scsi_dh_modules ${i##*/}"
 done
 
 save_var scsi_dh_modules
Index: 1220/mkinitrd/scripts/setup-sharedlibs.sh
===================================================================
--- 1220.orig/mkinitrd/scripts/setup-sharedlibs.sh
+++ 1220/mkinitrd/scripts/setup-sharedlibs.sh
@@ -54,58 +54,68 @@ shared_object_files() {
         while [ -L "/$lib" ]; do
             echo $lib
             link="$(readlink "/$lib")"
             if [ x"${link:0:1}" == x"/" ]; then
                 lib=${link#/}
             else
                 lib="${lib%/*}/$link"
             fi
         done
         echo $lib
     done
 }
 
-verbose -ne "Shared libs:\t"
-# Copy all required shared libraries and the symlinks that
-# refer to them.
-lib_files=$(shared_object_files "${initrd_bins[@]}")
-[ $? -eq 0 ] || return 1
-if [ -n "$lib_files" ]; then
-    for lib in $lib_files; do
-        [ -L $root_dir/$lib ] || verbose -n "$lib "
-        ( cd ${root_dir:-/} ; cp -dp --parents $lib $tmp_mnt )
-    done
-    lib_files=
+copy_shared_libs() {
+    local bins=( "$@" )
+    local extra_lib_files lib_files lib i
+
+    # First see what nss and other libs are required. This can be 64bit or 32bit,
+    # depending on the host and the already copied binaries.
     case "$(uname -m)" in
         ia64)
+            # this is a known location
             mkdir -p $tmp_mnt/lib
-            lib_files="$lib_files `echo $root_dir/lib/libnss_{dns,files}* $root_dir/lib/lib{gcc_s,unwind}.so*`"
+            extra_lib_files="`echo $root_dir/lib/libnss_{dns,files}* $root_dir/lib/lib{gcc_s,unwind}.so*`"
             ;;
         *)
-            # no symlinks, most point into the running system
-            for i in `LANG=C LC_ALL=C file -b $tmp_mnt/{,usr/}{lib*/udev/,{,s}bin}/* | sed -n 's/^ELF \([0-9][0-9]-bit\) .*/\1/p' | sort -u`
+            # Skip symlinks, they may point into the running system instead of $tmp_mnt
+            for i in `LANG=C LC_ALL=C file -b $tmp_mnt/{,usr/}{lib*/udev,{,s}bin}/* | sed -n 's/^ELF \([0-9][0-9]-bit\) .*/\1/p' | sort -u`
             do
                 case "$i" in
                     32-bit)
                         mkdir -p $tmp_mnt/lib
-                        lib_files="$lib_files `echo $root_dir/lib/libnss_{dns,files}* $root_dir/lib/libgcc_s.so*`"
+                        extra_lib_files="$extra_lib_files `echo $root_dir/lib/libnss_{dns,files}* $root_dir/lib/libgcc_s.so*`"
                         ;;
                     64-bit)
                         mkdir -p $tmp_mnt/lib64
-                        lib_files="$lib_files `echo $root_dir/lib64/libnss_{dns,files}* $root_dir/lib64/libgcc_s.so*`"
+                        extra_lib_files="$extra_lib_files `echo $root_dir/lib64/libnss_{dns,files}* $root_dir/lib64/libgcc_s.so*`"
                         ;;
                 esac
             done
             ;;
     esac
 
-    for lib in $lib_files ; do
-        if [ -f $lib ] ; then
-            verbose -n "${lib##$root_dir/} "
-            cp -dp --parents $lib $tmp_mnt
+    verbose -ne "Shared libs:\t"
+
+    # Now collect a list of libraries on which the binaries and extra libs depend on
+    lib_files=$( shared_object_files ${bins[@]} $extra_lib_files )
+    if [ $? -eq 0 ]
+    then
+        if [ -n "$lib_files" ]
+        then
+            # Finally copy dependencies and extra libs
+            for lib in $lib_files $extra_lib_files
+            do
+                [ -L $root_dir/$lib ] || verbose -n "$lib "
+                ( cd ${root_dir:-/} ; cp -dp --parents $lib $tmp_mnt )
+            done
+            verbose
+        else
+            verbose "none"
         fi
-    done
-    verbose
-else
-    verbose "none"
-fi
+    else
+        return 1
+    fi
+}
 
+# Copy all required shared libraries and the symlinks that refer to them.
+copy_shared_libs "${initrd_bins[@]}"