On 12/01/16 06:05 PM, Marco d'Itri wrote: > On Jan 12, Jason Rhinelander <jager...@jagerman.com> wrote: > > Thank you for testing the conversion program, for a start! > >> I installed usrmerge, and got the following during configuration: > This is expected and not a bug.
Right (was just reporting it for context). >> At this point, I examined the disk layout, and noticed that basically>> everything* in /{bin,sbin,lib} had been moved to /usr/{bin,sbin,lib}, and
>> replaced with symlinks in /{bin,sbin,lib}, but /{bin,sbin,lib} still >> existed as real directories (not symlinks). > If you got at that point then everything in the directories was either > a directory or a symlink. Yes, it appears it had just the final move-away-and-symlink step left. >> Since I couldn't figure out which daemon was causing the problem, I >> rebooted the system as suggested in the usrmerge configure error >> messages. It didn't come back up: it failed to start with an error that >> /sbin/init was not found on the disk. Oddly, however, I could run ls >> /sbin/init which *did* show an existing symlink and target. > Did you get a "No init found. Try passing init= bootarg." message, > exactly? > This check in the initramfs it is supposed to cope with absolute > symlinks, but I did not test this exact condition and it is the only > possible failure I can think about right now. The error was: Target filesystem doesn't have requested /sbin/initand 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/systemdand 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
smime.p7s
Description: S/MIME Cryptographic Signature