# copied root partition does not boot with initrd

## m27315

Hi,

Intro: I have a multi-boot setup.  (First disk, sda, has boot and Windows XP partitions.  Second disk, sdb, has Linux swap and root partitions.)  I cloned (rsync) my root partition from the old drive (sdb) to the root partitions of 2 newer drives (sdc and sdd).  Here's the actual command I used:

```
rsync -zax --delete --progress /old_root/ /new_root/
```

The data synchronized correctly; however, I cannot boot into the new root partition on the new drive using my initramfs image.  I use the initramfs, primarily because I refer to partitions by label name instead of the device letter and partition number, because those can change easily just by adding an eSATA backup drive.  So, I would really like to keep using an initramfs, if at all possible, to keep my setup as flexible as possible.

Problem: The problem I am experiencing is that I can continue to boot to the root of the old drive using its label and an initramfs, but if I use the same initramfs and the label of the new drive, the boot-up sequence freezes immediately after loading the kernel.  It never actually makes it onto to the new drive's root partition.

What am I missing?  Did I need to do something more than just an rsync for the root partition?

Things I Have Tried:

I copied this partition to 2 drives.  Both are having the same problem.  Both boot fine if I skip the initrd line, thereby avoiding the initramfs.

I have rebuilt the initramfs using the latest busybox and fbcondecor_helper (splash_helper), but the new initramfs freezes just like the old.

I have played with all the Grub boot options (see below) and narrowed the problem down to the combination of the initrd line and either of the new drives (new root partitions).

I have tried moving the problem drive to different SATA ports, including #1, and #2, but that does not help.

I have verified partition names using the e2label command.

I have got to be missing something, but I don't know what.

Any suggestions?

Thanks!

BTW, here's my consolidated grub.conf for reference:

```
splashimage=(hd0,1)/boot/grub/gentoo.xpm.gz

title Windows XP Pro SP3

rootnoverify (hd0,0)

makeactive

chainloader +1

title Gentoo Linux 3.1.4-gentoo NO INITRAMFS - NEW - WORKS

title Gentoo Linux 3.1.4-gentoo

root (hd0,1)

kernel /boot/kernel-3.1.4-gentoo root=/dev/sdc3 splash=silent,fadein,theme:livecd-2010.0 video=uvesafb:1280x720-32,mtrr:3,ywrap quiet console=tty1 fbcon=scrollback:256K rootfstype=ext4

title Gentoo Linux 3.1.4-gentoo WITH INITRAMFS - NEW - BROKE

root (hd0,1)

kernel /boot/kernel-3.1.4-gentoo root=LABEL=NEW_ROOT splash=silent,fadein,theme:livecd-2010.0 video=uvesafb:1280x720-32,mtrr:3,ywrap quiet console=tty1 fbcon=scrollback:256K rootfstype=ext4

initrd /boot/fbsplash-label-initramfs.cpio.gz

title Gentoo Linux 3.1.4-gentoo WITH INITRAMFS, BUT NO LABEL - NEW - BROKE

root (hd0,1)

kernel /boot/kernel-3.1.4-gentoo root=/dev/sdc3 splash=silent,fadein,theme:livecd-2010.0 video=uvesafb:1280x720-32,mtrr:3,ywrap quiet console=tty1 fbcon=scrollback:256K rootfstype=ext4

initrd /boot/fbsplash-label-initramfs.cpio.gz

title Gentoo Linux 3.1.4-gentoo WITH INITRAMFS - OLD - WORKS

root (hd0,1)

kernel /boot/kernel-3.1.4-gentoo root=LABEL=OLD_ROOT splash=silent,fadein,theme:livecd-2010.0 video=uvesafb:1280x720-32,mtrr:3,ywrap quiet console=tty1 fbcon=scrollback:256K rootfstype=ext4

initrd /boot/fbsplash-label-initramfs.cpio.gz
```

And, here's my initramfs' init script:

```
#!/bin/busybox sh

rescue_shell() {

    echo "Something went wrong. Dropping you to a shell."

    busybox --install -s

    exec /bin/sh

}

mini_udev() {

    echo /sbin/mdev > /proc/sys/kernel/hotplug

    mdev -s

}

uuidlabel_root() {

    for cmd in $(cat /proc/cmdline) ; do

        case $cmd in

        root=*)

            type=$(echo $cmd | cut -d= -f2)

            if [ $type == "LABEL" ] || [ $type == "UUID" ] ; then

                uuid=$(echo $cmd | cut -d= -f3)

                mount -o ro $(findfs "$type"="$uuid") /mnt/root

            else

                mount -o ro $(echo $cmd | cut -d= -f2) /mnt/root

            fi

            ;;

        esac

    done

}

# Mount the /proc and /sys filesystems.

mount -t proc none /proc

mount -t sysfs none /sys

# Launch mdev (mini_udev)

mini_udev

# Do your stuff here.

#echo "This script mounts rootfs and boots it up, nothing more!"

# Mount the root filesystem.

#mount -o ro /dev/sda1 /mnt/root

uuidlabel_root || rescue_shell

# Clean up.

umount /proc

umount /sys

# Boot the real thing.

exec switch_root /mnt/root /sbin/init
```

Reference: http://en.gentoo-wiki.com/wiki/Initramfs

----------

## tclover

When I started reading your post, I thought your init scripts might be at fault because you said you verified the LABEL, but now, after reading your init script--which is a minimal valid script--I can only think of a invalid LABEL. Again, you said the root LABEL is verified. Well, what you could do is using UUID instead of LABEL. And if that does not work... it should work, there's no reason it shouldn't! Or just modify your script to be dropped in that minimal shell and run `blkid` or `findfs $UUID[|$LABEL]` to make sure that you don't have odd stuff coming out findfs/blkid--sometimes I had unexpected output with busybox with no apparent reason.

----------

## frostschutz

I don't use uuid/label myself but someone changed this function in the wiki article recently. I don't know why / if the old one is wrong somehow / but you could give it a try anyway.

If you understand the script, the best way to debug it is to use the rescue shell. Busybox gives you a rather complete environment of simple command line tools. So go there, check it out, and see if you can mount your root fs and switch to it - if there is a problem with your setup it should become obvious at this point.

----------

## m27315

Thanks for the suggestions!   :Smile:   Based on your input, I used the rescue shell and an updated, modified init script to move closer to the root problem.  Apparently, the init script was working fine.  The last statement, the exec-switchroot is the culprit.  For some unknown reason, I cannot switchroot into the new root partition from the initramfs and busybox; however, I can boot to the partition directly from grub!

Suggestions?  I upgraded to a newer version of openrc a few weeks (months?) ago.  Does it hard-code anything?  Maybe I need to do something on the new partition to permit switchroot and /sbin/init to work correctly?  I'm grasping at straws...

Thanks!

For reference, here's my updated init with a new, neat feature to pull the rootfstype out of the command line and include that in the mount statement:

```
#!/bin/busybox sh

rescue_shell() {

    echo "Something went wrong. Dropping you to a shell."

    busybox --install -s

    exec /bin/sh

}

add_dhcp() {

    ifconfig eth0 up

         udhcpc -t 5 -q -s /bin/simple.script

}

mini_udev() {

    echo /sbin/mdev > /proc/sys/kernel/hotplug

    echo "(I) Launching mini-udev (mdev) ..."

    mdev -s

}

uuidlabel_root() {

    fstype=""

    for cmd in $(cat /proc/cmdline) ; do

        case $cmd in

        rootfstype=*)

           fstype="-t ${cmd#rootfstype=}"

           ;;

        esac

    done

    for cmd in $(cat /proc/cmdline) ; do

        case $cmd in

        root=*)

            dev=${cmd#root=}

            type=${dev%%=*}

            if [ $type = "LABEL" ] || [ $type = "UUID" ] ; then

                echo "(I) Mounting root partition: (type=${type}, device=${dev}, fstype=${fstype})"

                par=$(findfs "$dev")

                echo "    findfs $dev => ${par}"

                mount -o ro $fstype ${par} /mnt/root

            else

                mount -o ro $fstype ${dev} /mnt/root

            fi

            ;;

        esac

    done

}

# Mount the /proc and /sys filesystems.

mount -t proc none /proc

mount -t sysfs none /sys

# Launch mdev (mini_udev)

mini_udev

# Debug only

#echo "(I) Entering rescue shell ..."

#rescue_shell

# Mount the root filesystem.

#mount -o ro /dev/sda1 /mnt/root

uuidlabel_root || rescue_shell

# Clean up.

umount /proc

umount /sys

# Boot the real thing.

echo "(I) Mounted partitions:"

mount

echo "(I) Switching root to /mnt/root, running /sbin/init ..."

exec switch_root /mnt/root /sbin/init
```

Here are the results from using the new, more verbose, more robust init script, while trying to boot to the new root partition:

```
  Booting 'Gentoo Linux 3.1.4-gentoo'

root (hd0,1)

 Filesystem type is ext2fs, partition type 0x83

kernel /boot/kernel-3.1.4-gentoo root=LABEL=NEW_ROOT splash=silent,fadein,theme:livecd-2010.0 video=uvesafb:1280x720-32,mtrr:3,ywrap quiet console=tty1 fbcon=scrollback:256K rootfstype=ext4

   [Linux-bzImage, setup=0x3400, size=0x58f930]

initrd /boot/fbsplash-label-initramfs.cpio.gz

   [Linux-initrd @ 0x37a4b000, 0x5a4bd8 bytes]

(I) Launching mini-udev (mdev) ...

(I) Mounting root partition: (type=LABEL, device=LABEL=NEW_ROOT, fstype=-t ext4)

    findfs LABEL=NEW_ROOT => /dev/sdc3

(I) Mounted partitions:

/dev/sdc3 on /mnt/root type ext4 (ro)

(I) Switching root to /mnt/root, running /sbin/init ...
```

And, there it hangs indefinitely.   :Sad:   I tried changing the "silent" and "quiet" args to "verbose", which spits out a tons more information, but it did not produce any more information after this last line (i.e., switch_root).  How can I debug what's wrong with the switch_root and /sbin/init on the new partition?  Is there a log?  Can I force more verbose debugging info?

Thanks!

----------

## greyspoke

Interesting, I am trying to update my initramfs so as to mount /usr (which is on an lvm).  Though I am trying devtmpfs not mdev.

m27315 - Firstly, have you solved this?

Secondly, have you tried to mount --move from /dev to /mnt/root/dev just before the switch root?  Alternatively, umount /dev before you move on?

Possibly what mdev has done is getting in the way of sysinit and udev carryin on somehow.

----------

## Hu

I would eliminate the use of mdev and rely on devtmpfs instead.  In some cases, people have reported a need to redirect the std input/output of switch_root to /dev/console.

----------

## m27315

Well, I finally manged to get this to work on my new system, but I am not entirely sure what fixed the problem.  After a certain point, I was unable to reproduce the problem, so I was not able to completely isolate the cause.  However, I will provide notes on a few things I tried in order, just in case it helps someone else.

writable rootfs - For whatever reason, mounting the rootfs partition in rw instead of ro allowed me to switch_root successfully.  Unfortunately, the next hurdle encountered was that the console disappeared.  The last output I would see would be the switch_root command, and the next thing I would see would be the XDM (KDM, for me) login screen.  Even after pressing Ctrl+Alt+1 and jumping back to the main console, the normal service start-up messages never appeared.  Strangely, as I shutdown (or reboot), the service messages all appeared in the main console. ... Eventually, I would have to set this back to read-only to enable fsck to check the root partition, but making the rootfs read-writable is what got me over this first hurdle.

console redirection - I used the commands, "setconsole -r", "setconsole -r /dev/console", and "setconsole -r /mnt/root/dev/console" to no avail.  In interactive busybox console, these commands never caused me to lose the console or interfere with it.  And, in batch (init) mode, they could never bring back the console, after I lost it.

console redirection 2 - The switch_root command has a -c DEV option, which tells switchroot to remount the command to that device after switching.  It defaults to /dev/console, so explicitly setting it to /dev/console did not make any difference.

init overhaul - I started looking at the documentation again to see, if I could find any problems with my init script.  I overhauled it quite a bit, and somewhere in these multiple iterations, I was able to get proper startup from the initramfs.  I am including the new version just for record and comparison, but there is not much of substantial difference.  In fact, if I revert to the old init script in the above post, everything works fine.  So, this was not the ultimate solution.

mdev vs. devtmpfs - I already had devtmpfs configured in my kernel, and it was configured to auto-mount.  Maybe that was producing some weird interference?  I never tried turning it off in the kernel, but I was able to stop using mini-dev (mdev) in the init script and start using devtmpfs instead without any problems.  As far as I could tell, the substitution did not make any differences.  In fact, I can switch back and forth very easily, and it does not make any difference now.

static nodes - I suspect this was the key to the weird distinction all along, although I cannot explain it or reproduce it.  The original partition that could boot from a label had a static node in my initramfs image (/usr/src/initramfs/dev/sda3), and the new partition did not!  I would expect mdev to overwrite these, and when I checked later in my troubleshooting process, it was creating all the missing nodes.  However, it's the only distinction I have found that is consistent with the original problem.  As I said, I cannot recreate the problem now to test my theory, but this is what my gut is telling me.   :Wink: 

So, if I had to do this over again, here's what I would try:

Switch to either mdev or devtmpfs.  Don't try to use both, especially with automount for devtmpfs enabled in the kernel.

Maybe see what happens if the rootfs is mounted writable, but know that you will eventually have to leave it at readonly for fsck to function on the root partition.

Check if you have any weird static nodes setup in the initramfs.

Triple check, trouble-shoot, debug, and experiment with the init script.  Walk through the script line by line verifying that device nodes are being created when and where you expect.

Things I did not try:

Moving the initramfs's /dev partition to /mnt/root/dev before switching root.  A copy of the device nodes may have worked too, once the rootfs was mounted, assuming it was mounted writable.

Using mdev without any devtmpfs function in the kernel.

If I manage to reproduce the problem again (inadvertently, of course), then I'll play with mdev versus devtmpfs some more and maybe the mount moving.  But, until then, I'll leave you with my final init script, which includes some commented out commands for debugging.

If you think of anything else to try, please let me know.  The problem is gone, but I don't like disappearing problems.

Thanks!

/usr/src/initramfs/init

```
#!/bin/busybox sh

# Function for parsing command line options with "=" in them

# get_opt("init=/sbin/init") will return "/sbin/init"

get_opt() {

        #echo "$@" | cut -d "=" -f 2

        # this version works better for this script

        echo "${@#*=}"

}

rescue_shell() {

    echo "Something went wrong. Dropping you to a shell."

    busybox --install -s

    exec /bin/sh

}

add_dhcp() {

    ifconfig eth0 up

         udhcpc -t 5 -q -s /bin/simple.script

}

remote_rescue_shell() {

    # Bring up network interface

    ifconfig eth0 10.0.0.1 up

    # telnetd requires devpts

    mkdir -p /dev/pts

    mount -t devpts none /dev/pts

    # Start the telnet server

    telnetd

    # Continue with the local rescue shell

    rescue_shell

}

mini_udev() {

        echo /sbin/mdev > /proc/sys/kernel/hotplug

        echo "(I) Launching mini-udev (mdev) ..."

        mdev -s

}

# Mount the /proc and /sys filesystems.

echo "(I) Mounting proc and sysfs pseudo filesystems:"

mount -t proc none /proc

mount -t sysfs none /sys

# Disable kernel messages from popping onto the screen

echo 0 > /proc/sys/kernel/printk

#Create all the symlinks to /bin/busybox

#echo "(I) Installing busybox:"

#busybox --install -s

# Defaults:

newroot="/mnt/root"

rootdev=""

rootfstype="auto"

shell=""

# Parse command-line arguments and options:

for opt in $(cat /proc/cmdline); do

        case $opt in

                root\=*)

                        rootdev=$(get_opt $opt)

                        ;;

                rootfstype\=*)

                        rootfstype=$(get_opt $opt)

                        ;;

                shell\=*)

                        shell=$(get_opt $opt | tr '[A-Z]' '[a-z]')

                        ;;

        esac

done

# Launch mdev (mini_udev) ... or, devtmpfs, built into kernel:

echo "(I) Launching device recognition and node creation filesystems:"

# Launch mini-udev

#mini_udev

# Launch devtmpfs:

echo "(I) Mounting devtmpfs at /dev:"

mount -t devtmpfs none /dev

# Mount the root filesystem.

if [ -n "$rootdev" ] ; then

        type=${rootdev%%=*}

        if [ $type = "LABEL" ] || [ $type = "UUID" ] ; then

                echo "(I) Mounting root partition: (type=${type}, device=${rootdev}, fstype=${rootfstype})"

                par=$(findfs "$rootdev")

                echo "    findfs $rootdev => ${par}"

                mount -o ro -t $rootfstype ${par} $newroot || rescue_shell

        else

                mount -o ro -t $rootfstype ${rootdev} $newroot || rescue_shell

        fi

else

        echo "(W) No rootdev specified (rootdev=$rootdev):"

        echo "    Defaulting to EXT4 on /dev/sda3."

        mount -o ro -t ext4 /dev/sda3 /mnt/root || rescue_shell

fi

#echo "(I) Re-mounting root as read-only, if mounted as read-write:"

#mount -o remount,ro $newroot

echo "(I) Mounted partitions:"

mount

# Create device nodes, just in case mdev failed - NOT NECESSARY

#echo "(I) Creating necessary device nodes in $newroot/dev:"

# crw-rw-rw- 1 root tty  5, 0 2012-01-24 07:16:37.978000020 -0600 /dev/tty

# crw--w---- 1 root tty  4, 0 2012-01-24 07:16:37.978000020 -0600 /dev/tty0

# crw------- 1 root root 5, 1 2012-01-24 13:17:44.977833605 -0600 /dev/console

# crw-rw-rw- 1 root root 1, 3 2012-01-24 07:16:37.957000019 -0600 /dev/null

#mknod -m 0666 "$newroot/dev/tty"     c 5 0

#mknod -m 0620 "$newroot/dev/tty0"    c 4 0

#mknod -m 0600 "$newroot/dev/console" c 5 1

#mknod -m 0666 "$newroot/dev/null"    c 1 3

# Debug only, if requested

if [ "$shell" = "y" ] || [ "$shell" = "yes" ] ; then

        echo "(I) Entering debug rescue shell per request ..."

        echo "    Execute these commands to continue boot:"

        echo "    umount /dev /proc /sys"

        echo "    exec switch_root $newroot /sbin/init"

        rescue_shell

fi

# Clean up.

echo "(I) Unmount pseudo-filesystems, /dev, /proc, and /sys:"

# Do not unmount /dev for mdev - only unmount for devtmpfs.

umount /dev

umount /proc

umount /sys

# Boot the real thing.

echo "(I) Switching root to $newroot, running /sbin/init ..."

#setconsole -r $newroot/dev/console

exec switch_root $newroot /sbin/init

# This will only run if the above exec (switch_root) failed.

echo "(E) Failed to switch_root.  Dropping into busybox rescue shell:"

exec /bin/sh
```

----------

## blakedude

(I know this is a year later, but it may help people with the same problem).

I had this same problem - copied the root partition to a new SSD drive and the kernel would hang at the end of booting, and init would not run.  I figured out that it was because I copied the drive using rsync (while the root was running) and figured that some extra files were copied from the running root to the new (copy) root.  Upon examination, I discovered that the /dev directory of the copy was empty, so I copied the "files" from /dev.  The other directories (/proc, /sys, etc.) were empty, so no worries.  Now it finishes booting.  I should have copied the drive while the old root was unmounted using a livecd, but I took out my cdrom when I put in the SSD.

----------

## Hu

If you want to copy without mounts disrupting your view, you can bind mount the directory elsewhere and copy from the mount.  This will show you only the contents of the bound filesystem, but not any filesystems mounted on top of it.  For example, you can see your static /dev this way without unmounting the dynamic /dev that your running system is using.

----------

