Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Dec 2006 11:34:25 -0700 (MST)
From:      "M. Warner Losh" <imp@bsdimp.com>
To:        olli@lurza.secnetix.de
Cc:        erik.udo@gmail.com, freebsd-hackers@freebsd.org
Subject:   Re: Init.c, making it chroot
Message-ID:  <20061229.113425.-593217865.imp@bsdimp.com>
In-Reply-To: <200612291736.kBTHa9kj021368@lurza.secnetix.de>
References:  <20061228.134053.-1548238884.imp@bsdimp.com> <200612291736.kBTHa9kj021368@lurza.secnetix.de>

next in thread | previous in thread | raw e-mail | index | archive | help
----Next_Part(Fri_Dec_29_11_34_25_2006_113)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

In message: <200612291736.kBTHa9kj021368@lurza.secnetix.de>
            Oliver Fromme <olli@lurza.secnetix.de> writes:
: 
: M. Warner Losh wrote:
:  > BTW, here's a patch to test.  Since FreeBSD has kenv(2), the patch is
:  > actually very small.
: 
: OK, I tried it.  The patch applied cleanly to RELENG_6.
: The following line triggered a warning and caused the
: compilation to be aborted:
: 
:  > +	kenv(KENV_GET, "init_chroot", init_chroot, sizeof(init_chroot));
: 
: I get:
: 
:    /usr/src/sbin/init/init.c: In function `main':
:    /usr/src/sbin/init/init.c:245: warning: passing arg 2 of `kenv' discards qualifiers from pointer target type

looks like kenv on RELENG_6 hadn't been const poisoned :-(.

: It compiles without problems.  For testing I prepared an
: ISO image and put everything into a subdirectory called
: /chroot, except for /boot.  /boot/loader.conf contains
: these lines:
: 
:    init_path="/ochroot/sbin/init"
:    init_chroot="/ochroot"
: 
: When I boot the CD (with -v), it freezes after printing
: these lines:
: 
:    cd9660: RockRidge Extension
:    Lookup of /dev for devfs, error: 2
:    start_init: trying /ochroot/sbin/init

OK.  There's code in init to mount devfs, but it is disabled by
default.

The error message is from devfs_fixup.  Early in the kernel boot, just
before we mount root, the kernel executes devfs_first.  This mounts
devfs as / and creates a /dev -> / symlink.  This allows mounting and
the like to work.  Later, after we've mounted /, we do what linux
would call 'pivot root' and remount this devfs on / as /dev.  That's
devfs_fixup.

: It seems that the kernel looks for /dev before starting
: init, hence before the chroot.  So I created /dev in the
: ISO image and tried again.  Now the "devfs error 2" line
: doesn't appear anymore, but it still freezes after the
: "start_init" line.

I can understand that.  init doesn't try to mount devfs on /dev unless
you pass it -d.  The -d comes from the boot loader somehow, but I've
not threaded to see how it could be set.  It appears, from first
blush, that RB_SINGLE gets 's' set, but there's no way to get 'd'
set.  Maybe init_chroot should imply it.

: I suspect that init expects devfs to be mounted on /dev
: _inside_ the chroot (i.e. on /ochroot/dev in my case),
: but I'm not sure if that's really causing the freeze.
: Unfortunately I haven't been able to analyse the problem
: further.  Do you have an idea or hint?

Once we chroot, we need to have a sane environment inside the chroot.
Since the patches I posted chroot so early, /dev doesn't exist inside
of it...

: PS:  The init_chroot feature would also be useful for
: making a shared CD/DVD that contains a standard FreeBSD
: installation (with sysinstall and "fixit") and a bootable
: live FS such as FreeSBIE at the same time.

The desire for a feature similar to this has come up many times,
usually in one-on-one meetings.  I'm sold on its need.

I've enclosed a patch.  delphi@ also checked the return value of kenv
too, which is more documented an interface.

Warner

----Next_Part(Fri_Dec_29_11_34_25_2006_113)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="init_chroot.diff"

Index: init.c
===================================================================
RCS file: /cache/ncvs/src/sbin/init/init.c,v
retrieving revision 1.62
diff -u -r1.62 init.c
--- init.c	8 Jun 2006 14:04:36 -0000	1.62
+++ init.c	29 Dec 2006 18:32:22 -0000
@@ -55,6 +55,7 @@
 #include <db.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <kenv.h>
 #include <libutil.h>
 #include <paths.h>
 #include <signal.h>
@@ -187,6 +188,8 @@
 int
 main(int argc, char *argv[])
 {
+	char init_chroot[PATH_MAX];
+	char icname[] = "init_chroot";
 	int c;
 	struct sigaction sa;
 	sigset_t mask;
@@ -239,6 +242,13 @@
 	 */
 	openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH);
 
+	if (kenv(KENV_GET, icname, init_chroot, sizeof(init_chroot)) > 0) {
+		if (chdir(init_chroot) != 0 || chroot(".") != 0)
+			warning("Can't chroot to %s: %m", init_chroot);
+		else
+			devfs++;
+	}
+
 	/*
 	 * Create an initial session.
 	 */

----Next_Part(Fri_Dec_29_11_34_25_2006_113)----



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20061229.113425.-593217865.imp>