Thank you for the example--that was helpful to see how this works.

I have initramfs in Linux enabled and I've been using that for a long time. I 
should be able to use switch_root.

I followed the prior suggestion to skip the inittab and use a script. I put a 
script in /etc/init.d/rcS:

#!/bin/busybox sh

/bin/busybox echo "Running boot script..."
/bin/busybox echo "Mounting filesystems..."
/bin/busybox mount -t devpts devpts /dev/pts
/bin/busybox mount -t tmpfs tmpfs /dev/shm
/bin/busybox mount -t proc proc /proc
/bin/busybox mount -t sysfs sysfs /sys
/bin/busybox mount -t tmpfs tmpfs /tmp
/bin/busybox echo "Installing links for busybox..."
/bin/busybox --install -s
/bin/busybox echo /sbin/mdev > /proc/sys/kernel/hotplug
/bin/busybox mdev -s
/bin/busybox echo "mounting rootfs..."
/bin/busybox mount -t xfs /dev/vda /mnt
/bin/busybox echo "Swtiching root"
exec /sbin/switch_root -c /dev/console /mnt /sbin/init

This runs and gets to switch_root.

It does not switch_root though. It doesn't run the new roots inittab which is 
present.

I get something like this:

[    1.262512] XFS (vda): Ending recovery (logdev: internal)
Swtiching root

Please press Enter to activate this console.


BusyBox v1.33.1 (2021-06-10 08:53:34 EDT) built-in shell (ash)

/ # ls

Is there any good way to debug this switch_root?

The new root has /etc/inittab like this:

::sysinit:-/bin/ash
::sysinit:/bin/busybox echo "hello from /etc/inittab"

At the end of this file there are 12 null characters (^@) that show up in VIM 
after I boot in /etc/inittab. Those are not there initially. I can delete them, 
verify they are gone, and then see them again after boot.

I tried following the suggestion of booting directly to the new root by adding 
a kernel command at boot and that did not work.

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

That image does work because I can mount it. It's the same one I'd switch_root 
too.

That makes me wonder if there is something wrong with the image. It'x XFS and I 
have that in my kernel (I can mount and read it).


I appreciate all the help! Thank you.

Jeremy

________________________________
From: Jody Bruchon <[email protected]>
Sent: Monday, June 14, 2021 11:44 AM
To: Porter, Jeremy <[email protected]>
Subject: Re: switch_root and /etc/inittab

Hi Jeremy!

I'm attaching the '/init' from my from-scratch Linux environment, the Tritech 
Service System. The public release hasn't been updated for a long time, but it 
still uses the same init system. If you want to see it in action, look here:

https://www.jodybruchon.com/tritech-service-system/<https://urldefense.com/v3/__https://www.jodybruchon.com/tritech-service-system/__;!!KGKeukY!ndVE7hu0zLAhbkrANopCcyPdH0e7avFN9BnGZRFOTP3Z5V8yepQt6t_O7t3LY4LuRyywZR1AYxKY0A$>

This may help you to figure out how to switch_root correctly--it sure took me a 
long time to get it right myself. I believe you can't do it if any files on the 
existing system are open other than the switch_root binary itself, nor can you 
do it if your root isn't ramfs (so use of an initrd is mandatory), because part 
of the process is pivoting the root FS to a mountpoint and then tossing out the 
original tmpfs filesystem completely.

The reason I use switch_root is because ramfs (which initrd always gets 
decompressed into) allows anything that fills the filesystem to crash the 
kernel by attempting to allocate more space than RAM has available, but 
switch_root into a tmpfs instance and you can prevent that from happening, so 
the initrd in mine is just enough stuff to switch over to tmpfs and hand 
control over to the real init system I use (also shell scripts, but using 
BusyBox runit for service controls).

I really hope this helps. Feel free to ask any questions you may have. I'm 
happy to help.

Jody Bruchon

On 2021-06-14 10:35, Porter, Jeremy wrote:
Thanks Ján!

I'm not sure I completely understand though. Doesn't "exec" make it run as PID 
1?

I suppose I need to start /dev/console before switching the root if I'm going 
to use that in the command to redirect there after switch_root.

In my inittab

::sysinit:/bin/busybox mount -t devpts devpts /dev/pts
::sysinit:/bin/busybox mount -t tmpfs tmpfs /dev/shm
::sysinit:/bin/busybox mount -t proc proc /proc
::sysinit:/bin/busybox mount -t sysfs sysfs /sys
::sysinit:/bin/busybox mount -t tmpfs tmpfs /tmp
::sysinit:/bin/busybox --install -s
::sysinit:/bin/busybox echo /sbin/mdev > /proc/sys/kernel/hotplug
::sysinit:/bin/busybox mdev -s
::sysinit:/bin/busybox mount -t xfs /dev/vda /mnt
/dev/console::sysinit:-/bin/ash
::sysinit:/bin/init.sh
::respawn:-/bin/ash

In my init.sh script

#/bin/bash
echo "Swtiching root"
exec /sbin/switch_root -c /dev/console /mnt /sbin/init
echo "Switched root"

This does not switch root either.

I don't quite understand the boot flow. Can you walk through what needs to 
happen here?

Thanks!

Jeremy
________________________________
From: Ján Sáreník <[email protected]><mailto:[email protected]>
Sent: Sunday, June 13, 2021 1:41 AM
To: Porter, Jeremy 
<[email protected]><mailto:[email protected]>; 
[email protected]<mailto:[email protected]> 
<[email protected]><mailto:[email protected]>
Subject: Re: switch_root and /etc/inittab

Hi Jeremy!

On Fri, Jun 11, 2021 at 2:39 PM Porter, Jeremy
<[email protected]><mailto:[email protected]> wrote:
>
>
> I'm working on a RISC-V Linux system that uses busybox and switch_root. My 
> goal is to build and include a tool chain (GDB, GCC, etc) into this RISC-V 
> Linux. I figured I could create a non-volatile image and attach that in QEMU, 
> which works fine. What is not working is the "switch_root" portion. I know it 
> needs to run at PID 1 and to use "exec". But that doesn't cut it. It runs, 
> but doesn't switch root. I'll post my inittab files below.
>
> This is the inittab on the initramfs:
>
> ::sysinit:/bin/busybox mount -t devpts devpts /dev/pts
> ::sysinit:/bin/busybox mount -t tmpfs tmpfs /dev/shm
> ::sysinit:/bin/busybox mount -t proc proc /proc
> ::sysinit:/bin/busybox mount -t sysfs sysfs /sys
> ::sysinit:/bin/busybox mount -t tmpfs tmpfs /tmp
> ::sysinit:/bin/busybox --install -s
> ::sysinit:/bin/busybox echo /sbin/mdev > /proc/sys/kernel/hotplug
> ::sysinit:/bin/busybox mdev -s
> ::sysinit:/bin/busybox mount -t xfs /dev/vda /mnt
> /dev/console::sysinit:-/bin/ash

Instead of running the init straight, there is possibility of using an
initial shell script (e.g. init=/my/script.sh in bootloader) and then
this script would contain the lines from inittab (quoted above)
including execing switch_root in the end.

So the boot would look like this (all PID 1 here):
  1. /my/script.sh, execs switch_root /new/root /bin/init
  2. /bin/init (on new root, will read /etc/inittab on new root)

The reason it did not work for you is that init itself was run as PID
1 and it is not a shell so it does not have any `exec ...` syntax
(yet, I mean the busybox init).

> When I run switch_root it executes and just hangs with no console so I added 
> the line:
>
> ::respawn:-/bin/ash
>
> which now returns to console like I want. However, it didn't switch_root 
> after I run:
>
> exec switch_root -c /dev/console /mnt /sbini/init
>
> I am still on the initramfs and I still have the new root on /mnt
>
> I also noticed that switch_root runs this /etc/inittab no matter what -- even 
> if I delete it -- when I run switch_root. I guess I was expected the new file 
> system's inittab to take over and I could just have a few lines to run. The 
> primary function would be to get back to the console with ::respawn:-/bin/ash.
>
> What am I missing?

It can not work in the shell run by that respawn line because that
spawned shell is not PID 1.

Hoping this helps,
best regards, Ján



_______________________________________________
busybox mailing list
[email protected]<mailto:[email protected]>
http://lists.busybox.net/mailman/listinfo/busybox<https://urldefense.com/v3/__http://lists.busybox.net/mailman/listinfo/busybox__;!!KGKeukY!ndVE7hu0zLAhbkrANopCcyPdH0e7avFN9BnGZRFOTP3Z5V8yepQt6t_O7t3LY4LuRyywZR1PpEnNFQ$>


_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to