[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#810860: usrmerge: System cannot be rebooted after partial usrmerge installation



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 <jagerman@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 to: