Date: Wed, 3 Jan 2007 11:51:22 +0200 From: "Erik Udo" <erik.udo@gmail.com> To: freebsd-hackers@freebsd.org Subject: Re: Init.c, making it chroot Message-ID: <6e3d78920701030151o3bcbf129yeff694d9f064985f@mail.gmail.com> In-Reply-To: <4592C91C.2040801@gmail.com> References: <4592C91C.2040801@gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] I just made patch. It's supposed to run /etc/rc before chrooting. This is the NetBSD "way" of doing it. All i can say is that it compiled. So if anyone can look at it before i get to test it becouse i might be forgetting something. (i can't even test it now) diff attached. On 12/27/06, Erik Udo <erik.udo@gmail.com> wrote: > > How can i make init chroot after executing /etc/rc, and executing > /etc/rc again in the chrooted enviroment? > > For this to work, i'd like to know at what point do i call chroot(), > becouse init.c uses fork() at the point where it runs the rc script. > > The thing is, i want to run a whole system in a chrooted enviroment in > this livecd i'm making. But the command "chroot /mnt/root /etc/rc" > returns after the /etc/rc has been run, dropping me back from the > chrooted enviroment. And if it doesn't, init never starts the multiuser > mode. > > So how can i go to the multiuser mode in a chrooted enviroment? I guess > the only way to do that is to modify init.c > > Any help/feedback is appreciated. > > Cheers, Erik > > _______________________________________________ > freebsd-hackers@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers > To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org" > [-- Attachment #2 --] --- init.c.orig Wed Jan 3 09:17:33 2007 +++ init.c Wed Jan 3 10:08:38 2007 @@ -67,6 +67,7 @@ #include <unistd.h> #include <sys/reboot.h> #include <err.h> +#include <kenv.h> #include <stdarg.h> @@ -115,6 +116,7 @@ state_func_t single_user(void); state_func_t runcom(void); +state_func_t runetcrc(int trychroot); state_func_t read_ttys(void); state_func_t multi_user(void); state_func_t clean_ttys(void); @@ -175,12 +177,17 @@ void clear_session_logs(session_t *); +int shouldchroot(void); +char init_chroot[PATH_MAX]; +int did_multiuser_chroot; + int start_session_db(void); void add_session(session_t *); void del_session(session_t *); session_t *find_session(pid_t); DB *session_db; + /* * The mother of all processes. */ @@ -718,6 +725,38 @@ state_func_t runcom(void) { + state_func_t next_step; + + /* Run /etc/rc and choose next state depending on the result. */ + next_step = runetcrc(0); + if (next_step != (state_func_t) read_ttys) + return (state_func_t) next_step; + + if (shouldchroot()) { + next_step = runetcrc(1); + if (next_step != (state_func_t) read_ttys) + return (state_func_t) next_step; + + did_multiuser_chroot = 1; + } else { + did_multiuser_chroot = 0; + } + + /* + * Regardless of whether in chroot or not, we booted successfuly. + * It's time to spawn gettys (ie. next_step's value at this point). + */ + runcom_mode = AUTOBOOT; /* the default */ + logwtmp("~", "reboot", ""); + return (state_func_t) read_ttys; +} + +/* + * Run the system startup script. + */ +state_func_t +runetcrc(int trychroot) +{ pid_t pid, wpid; int status; char *argv[4]; @@ -743,6 +782,12 @@ sigprocmask(SIG_SETMASK, &sa.sa_mask, (sigset_t *) 0); + if (trychroot) + if (chroot(init_chroot) != 0) { + warning("failed to chroot to `%s': %m", + init_chroot); + _exit(1); /* force single user mode */ + } #ifdef LOGIN_CAP setprocresources(RESOURCE_RC); #endif @@ -803,9 +848,6 @@ if (WEXITSTATUS(status)) return (state_func_t) single_user; - runcom_mode = AUTOBOOT; /* the default */ - /* NB: should send a message to the session logger to avoid blocking. */ - logwtmp("~", "reboot", ""); return (state_func_t) read_ttys; } @@ -1633,3 +1675,22 @@ } } #endif + + +int shouldchroot(void) { + char icname[] = "init_chroot"; + *init_chroot = '\0'; + + if(kenv(KENV_GET, icname, init_chroot, + sizeof(init_chroot)) == -1) { + warning("Can't fetch init_chroot from kenv(): %m"); + return 0; + } + + if (chdir(init_chroot) != 0 || chroot(".") != 0) { + warning("Can't chroot to %s: %m", init_chroot); + return 0; + } + + return 1; +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6e3d78920701030151o3bcbf129yeff694d9f064985f>
