Page MenuHomeFreeBSD

init(8): extract reroot transient code into reroot_seed
Needs ReviewPublic

Authored by kib on Fri, Jul 10, 7:40 PM.
Tags
None
Referenced Files
F162322357: D58164.id181756.diff
Sun, Jul 12, 1:21 AM
Unknown Object (File)
Fri, Jul 10, 9:23 PM
Unknown Object (File)
Fri, Jul 10, 7:46 PM
Subscribers
None

Details

Summary
Since init become dynamically linked, reroot appeared to be broken
because init copies itself into a transient tmpfs mount to continue
controlling execution right after the reboot(REROOT) syscall.  Because
the binary is dynamically linked, it cannot be properly executed.

Provide a minimal static binary 'reroot_seed' embedded into the init as
byte stream, which performs what the 'init -r' did, namely, the second
phase reroot.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

kib requested review of this revision.Fri, Jul 10, 7:40 PM
kib created this revision.

This is not finished, I need some help with the build system.

First, the reroot_seed binary should not be installed. I do not see how to specify this with the bsd.prog.mk.

Second, reroot_seed must be a dependency for reroot_seed.embed.s, but again it is not clear to me how to enforce this, esp. the requirement that the sbin/init/reroot_seed subdirectory is visited before the sbin/init directory.

Add INTERNALPROG to reroot_seed to avoid installation.

In D58164#1333865, @kib wrote:

This is not finished, I need some help with the build system.

First, the reroot_seed binary should not be installed. I do not see how to specify this with the bsd.prog.mk.

I guess this one is solved with INTERNALPROG.

Second, reroot_seed must be a dependency for reroot_seed.embed.s, but again it is not clear to me how to enforce this, esp. the requirement that the sbin/init/reroot_seed subdirectory is visited before the sbin/init directory.

I do not know how to do this. If you have two subdirectories, sbin/init/init and sbin/init/reroot_seed, then you can write something like

SUBDIR= reroot_seed \
        .WAIT \
        init

and I think that will do what you want, but this requires a separate directory for the main init.

In D58164#1333865, @kib wrote:

This is not finished, I need some help with the build system.

First, the reroot_seed binary should not be installed. I do not see how to specify this with the bsd.prog.mk.

I guess this one is solved with INTERNALPROG.

Yes, already did that.

Second, reroot_seed must be a dependency for reroot_seed.embed.s, but again it is not clear to me how to enforce this, esp. the requirement that the sbin/init/reroot_seed subdirectory is visited before the sbin/init directory.

I do not know how to do this. If you have two subdirectories, sbin/init/init and sbin/init/reroot_seed, then you can write something like

SUBDIR= reroot_seed \
        .WAIT \
        init

and I think that will do what you want, but this requires a separate directory for the main init.

I will move reroot_seed to sbin/ instead.
Thanks.

Move reroot_seed to sbin/. Use .WAIT between reroot_seed and init.

sbin/init/reroot_seed.embed.s
3

This file is in the objdir, right? How will the assembler find it?

The patch fails to build for me with /home/markj/sb/main/src/sbin/init/reroot_seed.embed.s:3:10: error: Could not find incbin file 'reroot_seed'

sbin/init/reroot_seed.embed.s
3

sbin/init/Makefile has the following:

ACFLAGS.reroot_seed.embed.s+=-I${.OBJDIR}/../reroot_seed

The build fails on the rescue build, real /sbin/init builds fine.

Why not have /libexec/reroot and just copy that instead?

In D58164#1333904, @imp wrote:

Why not have /libexec/reroot and just copy that instead?

I want init to be self-contained. I could imagine that somebody doing reroot would only copy /sbin/init and libs and not /libexec/reroot.

sbin/init/reroot_seed.embed.s
3

Is there a way to correctly and reliably name the sbin/reroot_seed objdir?
${OBJTOP}/sbin/reroot_seed does not work for rescue.

Bryan, could you please help there with the build system?

The problem for me is that I have a helper binary sbin/reroot_seed for sbin/init, and I need to get the path to the object directory for reroot_seed during the init build. The ${OBJTOP}/sbin/reroot_seed (as well as ${.OBJDIR}/../reroot_seed) works for the normal build of the init itself, but fails for the rescue crunch. In the rescue stage, I still need the ${OBJTOP}/sbin/reroot_seed` path, but OBJTOP is pointing to the crunch obj dir.

It is useless to add reroot_seed to the rescue build, because I need a final binary to embed into init, and not crunched object.

Restore the inline reroot code and use it for the static build as part of the rescue crunch.

I was unable to find the solution for the rescue changing OBJTOP, but this work-around might be even better.