Control: clone 810860 -1
Control: severity -1 important
Control: reassign -1 initramfs-tools
Control: tag -1 patch
Control: retitle -1 initramfs-tools does not follow recursive symlinks

initramfs-tools needs this patch to be able to resolve recursive 
symlinks, or else the system will not boot while in the middle of 
a merged /usr transition.
Then I will add a versioned conflict to the usrmerge package.

On Jan 13, Jason Rhinelander <jager...@jagerman.com> wrote:

[...]
> The error was:
> 
> Target filesystem doesn't have requested /sbin/init
> 
> and so it indeed appears to be validate_init in initramfs-tools/init not
> coping with the intermediate usrmerge setup.
> 
> Taking a quick look at it, it looks like validate_init will only handle a
> *single* absolute symlink, but in this particular case there are two
> (absolute) symlinks:
> 
> /sbin/init -> /usr/sbin/init
> /usr/sbin/init -> /lib/systemd/systemd
> 
> and so it resolves the first to ${rootmnt}/usr/sbin/init, but not the
> second, and so init is still a broken symlink.
> 
> I've attached a patch for initramfs-tools to cope with this by resolving
> symlinks in a loop (up to a maximum of 10 times, to avoid an infinite loop
> for potential symlink cycles) instead of just once, which should fix the
> problem. It seems to work with an artificial nest of various symlinks (both
> absolute and relative) that I created, though I didn't replicate the
> usrmerge intermediate step to actually test it there.
> 
> 
> Jason Rhinelander

> --- a/init    2016-01-13 10:50:25.928550244 -0500
> +++ b/init    2016-01-13 11:08:19.900426244 -0500
> @@ -234,15 +234,20 @@
>       checktarget="${1}"
>  
>       # Work around absolute symlinks
> -     if [ -d "${rootmnt}" ] && [ -h "${rootmnt}${checktarget}" ]; then
> -             checktarget="$(readlink "${rootmnt}${checktarget}")"
> -             case "$checktarget" in
> -             /*)
> -                     ;;
> -             *)
> -                     checktarget="${1%/*}/$checktarget"
> -                     ;;
> -             esac
> +     if [ -d "${rootmnt}" ]; then
> +        readlink_count=0
> +        while [ -h "${rootmnt}${checktarget}" ] && [ "$readlink_count" -lt 
> 10 ]; do
> +            lasttarget="${checktarget}"
> +            checktarget="$(readlink "${rootmnt}${checktarget}")"
> +            readlink_count=$((readlink_count+1))
> +            case "$checktarget" in
> +            /*)
> +                ;;
> +            *)
> +                checktarget="${lasttarget%/*}/$checktarget"
> +                ;;
> +            esac
> +        done
>       fi
>  
>       # Make sure the specified init can be executed




-- 
ciao,
Marco

Attachment: signature.asc
Description: PGP signature

Reply via email to