Search
j0ke.net Open Build Service
>
Projects
>
home:jg
:
playground
>
dracut
> 0287-dracut-functions-create-relative-symlinks-in-the-ini.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File 0287-dracut-functions-create-relative-symlinks-in-the-ini.patch of Package dracut
From 6dd298ff9b85dc88c588b76c59964a8da3208458 Mon Sep 17 00:00:00 2001 From: Harald Hoyer <harald@redhat.com> Date: Wed, 3 Oct 2012 11:58:11 -0400 Subject: [PATCH] dracut-functions: create relative symlinks in the initramfs Resolves: rhbz#857048 --- dracut-functions | 145 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 119 insertions(+), 26 deletions(-) diff --git a/dracut-functions b/dracut-functions index 82beb01..97f55f6 100755 --- a/dracut-functions +++ b/dracut-functions @@ -49,6 +49,92 @@ derror() { [[ -w $dracutlogfile ]] && echo $(date) "Err:" $@ >>"$dracutlogfile" } + + +# normalize_path <path> +# Prints the normalized path, where it removes any duplicated +# and trailing slashes. +# Example: +# $ normalize_path ///test/test// +# /test/test +normalize_path() { + shopt -q -s extglob + set -- "${1//+(\/)//}" + shopt -q -u extglob + echo "${1%/}" +} + +# convert_abs_rel <from> <to> +# Prints the relative path, when creating a symlink to <to> from <from>. +# Example: +# $ convert_abs_rel /usr/bin/test /bin/test-2 +# ../../bin/test-2 +# $ ln -s $(convert_abs_rel /usr/bin/test /bin/test-2) /usr/bin/test +convert_abs_rel() { + local __current __absolute __abssize __cursize __newpath + local -i __i __level + + set -- "$(normalize_path "$1")" "$(normalize_path "$2")" + + # corner case #1 - self looping link + [[ "$1" == "$2" ]] && { echo "${1##*/}"; return; } + + # corner case #2 - own dir link + [[ "${1%/*}" == "$2" ]] && { echo "."; return; } + + IFS="/" __current=($1) + IFS="/" __absolute=($2) + + __abssize=${#__absolute[@]} + __cursize=${#__current[@]} + + while [[ ${__absolute[__level]} == ${__current[__level]} ]] + do + (( __level++ )) + if (( __level > __abssize || __level > __cursize )) + then + break + fi + done + + for ((__i = __level; __i < __cursize-1; __i++)) + do + if ((__i > __level)) + then + __newpath=$__newpath"/" + fi + __newpath=$__newpath".." + done + + for ((__i = __level; __i < __abssize; __i++)) + do + if [[ -n $__newpath ]] + then + __newpath=$__newpath"/" + fi + __newpath=$__newpath${__absolute[__i]} + done + + echo "$__newpath" +} + +# returns OK if $1 contains $2 at the beginning +str_starts() { + [ "${1#$2*}" != "$1" ] +} + +ln_r() { + local _source=$1 + local _dest=$2 + + if ! str_starts "$_source" "/"; then + ln -sfn "$_source" "${initdir}/${_dest}" + else + [[ -d "${_dest%/*}" ]] && _dest=$(readlink -f "${_dest%/*}")/${_dest##*/} + ln -sfn $(convert_abs_rel "${_dest}" "${_source}") "${initdir}/${_dest}" + fi +} + get_fs_env() { if [[ -x /lib/udev/vol_id ]]; then eval $(/lib/udev/vol_id --export $1) @@ -134,31 +220,28 @@ check_vol_slaves() { } # Install a directory, keeping symlinks as on the original system. -# Example: if /lib64 points to /lib on the host, "inst_dir /lib/file" +# Example: if /lib points to /lib64 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" + [[ -e ${initdir}/"$1" ]] && return 0 # already there + + local _dir="$1" _part="${1%/*}" _file + while [[ "$_part" != "${_part%/*}" ]] && ! [[ -e "${initdir}/${_part}" ]]; do + _dir="$_part $_dir" + _part=${_part%/*} + done + + # iterate over parent directories + for _file in $_dir; do + [[ -e "${initdir}/$_file" ]] && continue + if [[ -L $_file ]]; then + inst_symlink "$_file" else # create directory - mkdir -p "${initdir}$file" || return 1 + mkdir -m 0755 -p "${initdir}/$_file" || return 1 + [[ -e "$_file" ]] && chmod --reference="$_file" "${initdir}/$_file" + chmod u+w "${initdir}/$_file" fi done } @@ -198,7 +281,7 @@ inst_library() { lib=${src##*/} inst_simple "$reallib" "$reallib" inst_dir "${dest%/*}" - (cd "${initdir}${dest%/*}" && ln -s "$reallib" "$lib") + ln_r "$reallib" "$dest" else inst_simple "$src" "$dest" fi @@ -272,12 +355,22 @@ inst_script() { # same as above, but specialized for symlinks inst_symlink() { - local src=$1 target=$initdir${2:-$1} realsrc + local _src=$1 _target=${2:-$1} _realsrc + strstr "$1" "/" || return 1 [[ -L $1 ]] || return 1 - [[ -L $target ]] && return 0 - realsrc=$(readlink -f "$src") - [[ $realsrc = ${realsrc##*/} ]] && realsrc=${src%/*}/$realsrc - inst "$realsrc" && ln -s "$realsrc" "$target" + [[ -L $initdir/$_target ]] && return 0 + _realsrc=$(readlink -f "$_src") + [[ ${_realsrc#/} = ${_realsrc} ]] && _realsrc="${_src%/*}/${_realsrc}" + if ! [[ -e $initdir/$_realsrc ]]; then + if [[ -d $_realsrc ]]; then + inst_dir "$_realsrc" + else + inst "$_realsrc" + fi + fi + [[ ! -e $initdir/${_target%/*} ]] && inst_dir "${_target%/*}" + + ln_r "${_realsrc}" "${_target}" } # find a udev rule in the usual places. -- 1.8.3.1