]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
dir symlinks
authorLance Albertson <lance@osuosl.org>
Sun, 27 Sep 2009 04:33:41 +0000 (21:33 -0700)
committerHarald Hoyer <harald@redhat.com>
Tue, 29 Sep 2009 17:01:29 +0000 (19:01 +0200)
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

dracut
dracut-functions

diff --git a/dracut b/dracut
index a74a3d321bd7ae0cff3b90819f23ad35182657ed..3ab92928c986f9afac74b6a72956599a0903f0b4 100755 (executable)
--- 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
 
index 2abd6f2d5755232128ff63d5de97257f4aba4a9f..1f2d1e617f50d7e5640a847e1b48357044615340 100755 (executable)
@@ -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##*/}"