From: Lance Albertson Date: Sun, 27 Sep 2009 04:33:41 +0000 (-0700) Subject: dir symlinks X-Git-Tag: 003~154 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=19612483396681ee5fb3e7bd98263c55ff132c68;p=thirdparty%2Fdracut.git dir symlinks On amd64 multilib Gentoo, /lib is a symlink to /lib64, and dracut creates duplicate files in /lib and /lib64 in a resulting cpio image. Other files are missing in /lib64 but exists in /lib in that image. So /usr/sbin/lvm fails to run from initrd due to missing libraries. A possible solution is to create in the initrd the same /lib symlink as in host system, if /lib is a symlink. http://bugs.gentoo.org/show_bug.cgi?id=278442#c10 --- diff --git a/dracut b/dracut index a74a3d321..3ab92928c 100755 --- a/dracut +++ b/dracut @@ -179,7 +179,7 @@ export initdir hookdirs dsrc dracutmodules drivers \ if [[ $kernel_only != yes ]]; then # Create some directory structure first for d in bin sbin usr/bin usr/sbin usr/lib etc proc sys sysroot tmp dev/pts var/run; do - mkdir -p "$initdir/$d"; + inst_dir "/$d"; done fi diff --git a/dracut-functions b/dracut-functions index 2abd6f2d5..1f2d1e617 100755 --- a/dracut-functions +++ b/dracut-functions @@ -131,6 +131,36 @@ check_vol_slaves() { return 1 } +# Install a directory, keeping symlinks as on the original system. +# Example: if /lib64 points to /lib on the host, "inst_dir /lib/file" +# will create ${initdir}/lib64, ${initdir}/lib64/file, +# and a symlink ${initdir}/lib -> lib64. +inst_dir() { + local dir="$1" + [[ -e "${initdir}$dir" ]] && return 0 + + # iterate over parent directories + local file="" + local IFS="/" + for part in $dir; do + [ -z "$part" ] && continue + file="$file/$part" + [[ -e "${initdir}$file" ]] && continue + + if [ -L "$file" ]; then + # create link as the original + local target=$(readlink "$file") + ln -sfn "$target" "${initdir}$file" || return 1 + # resolve relative path and recursively install destionation + [[ "$target" = "${target##*/}" ]] && target="${file%/*}/$target" + inst_dir "$target" + else + # create directory + mkdir -p "${initdir}$file" || return 1 + fi + done +} + # $1 = file to copy to ramdisk # $2 (optional) Name for the file on the ramdisk # Location of the image dir is assumed to be $initdir @@ -138,11 +168,11 @@ check_vol_slaves() { inst_simple() { local src target [[ -f $1 ]] || return 1 - src=$1 target=${initdir}${2:-$1} - [[ -f $target ]] && return 0 - mkdir -p "${target%/*}" + src=$1 target="${2:-$1}" + [[ -f ${initdir}$target ]] && return 0 + inst_dir "${target%/*}" dinfo "Installing $src" - cp -pfL "$src" "$target" + cp -fL "$src" "${initdir}$target" } # Same as above, but specialzed to handle dynamic libraries. @@ -155,7 +185,7 @@ inst_library() { reallib=$(readlink -f "$src") lib=${src##*/} inst_simple "$reallib" "$reallib" - mkdir -p "${initdir}${dest%/*}" + inst_dir "${dest%/*}" (cd "${initdir}${dest%/*}" && ln -s "$reallib" "$lib") else inst_simple "$src" "$dest" @@ -250,7 +280,8 @@ find_rule() { # create a function to install them to make life simpler. inst_rules() { local target=/etc/udev/rules.d - mkdir -p "$initdir/lib/udev/rules.d" "$initdir$target" + inst_dir "/lib/udev/rules.d" + inst_dir "$target" for rule in "$@"; do rule=$(find_rule "$rule") && \ inst_simple "$rule" "$target/${rule##*/}"