Search:  
Gentoo Wiki

HOWTO_Gentoo_in_chroot


This article is part of the HOWTO series.
Installation Kernel & Hardware Networks Portage Software System X Server Gaming Non-x86 Emulators Misc

Contents

Gentoo in chroot

The idea here is to have a complete Gentoo system in a persistent chroot environment on any other linux (with a sufficiently modern kernel), which allows the starting and stopping of services in the gentoo system.

Essentially what this is is a standard installation of Gentoo which is interrupted before the end and put into a stable state for using in the installation chroot system. Most of the process of installation actually refers to the standard Gentoo Handbook; we use the host Linux in place of a Gentoo Live/Installation CD and just start partway in and stop before the end, then we make some minor init-script changes to stop Gentoo doing antisocial things like killing the host, and write some start/stop scripts.

Why would anyone want to do this? In my case the starting point was wanting to have a more useful environment on quite old Fedora / RHEL installations, where they were of versions no longer being supported but where upgrading the base system wasn't an option for all sorts of reasons that are just too painful to go into.

Since then I found other uses: as a way of staging services to a new configuration inside a colo Gentoo-ppc install; and running a sane, functional, useful version of netatalk on an Ubuntu Hardy Alpha install. In the latter case, setting up an entire Gentoo system just for netatalk is overkill, but given I already had it set up for experimental purposes it was the quickest way to resolve the broken-netatalk issues in Ubuntu itself. (As a bonus, the gentoo-build of netatalk appears to transfer files faster than the less-broken ubuntu-gutsy build.)

Caveat

You can think of this as a very extremely poor-man's virtualisation, that requires the absolute minimum disruption of the host (no new system software, no new kernel modules or kernel builds...). But it is only chroot, and you probably shouldn't give anyone privileges on the chrooted gentoo system that you wouldn't be comfortable with them having on the host.

Prerequisites

A host Linux system that's sufficiently functional, where:

Preparing the ground

This is very simple. Decide where you want the gentoo system to live. It doesn't have to be a partition, although there's no reason why it can't be. For the purposes of this howto we're going to set an environment variable GENTOO.

Become root.

host ~#
export GENTOO=/gentooImage:CursorOFF.gif
host ~#
mkdir -p $GENTOOImage:CursorOFF.gif

Installing

This section mostly recaps the Gentoo Handbook from section 5 (Installing the Gentoo Installation files) through to section 9 (Necessary and optional system tools). What follows is a very truncated recap, and you may wish to follow the handbook as you go.

Fetching the Stage3 and Portage snapshot files.

Use whatever browser/downloader the host Linux has to fetch the current stage3 file for your host system's architecture and the portage snapshot.

Once you have them,

host ~#
cd $GENTOOImage:CursorOFF.gif
host ~#
tar xvfjp stage3*.tar.bz2Image:CursorOFF.gif
host ~#
tar xvjf portage-latest.tar.bz2 -C $GENTOO/usrImage:CursorOFF.gif

Compile options

Edit /etc/make.conf as required. (It's probably safe to leave it untouched for now though.)

host ~#
vi $GENTOO/etc/make.confImage:CursorOFF.gif

Selecting mirrors

The chances are your host linux system doesn't have mirrorselect installed (unless it is itself a Gentoo system), so we'll leave the mirror setup for now. You can of course put the GENTOO_MIRRORS line in by hand if you know what you want.

Copy DNS info

You can just do what the handbook says:

host ~#
cp -L /etc/resolv.conf $GENTOO/etc/resolv.confImage:CursorOFF.gif

But given the host is going to survive this process this might be an occasion for a hard link, so the Gentoo system benefits from any later configuration changes to DNS on the host:

host ~#
ln /etc/resolv.conf $GENTOO/etc/resolv.confImage:CursorOFF.gif

(NB: This solution on its own probably won't be sufficient if you're using resolvconf on the host.)

Mount /proc and /dev

Just like in the handbook...

host ~#
mount -t proc none $GENTOO/procImage:CursorOFF.gif
host ~#
mount -o bind /dev $GENTOO/devImage:CursorOFF.gif

Entering the new environment

host ~#
chroot $GENTOO /bin/bashImage:CursorOFF.gif
/ ~#
env-updateImage:CursorOFF.gif
/ ~#
source /etc/profileImage:CursorOFF.gif
/ ~#
export PS1="(gentoo) $PS1"Image:CursorOFF.gif
gentoo ~#
Image:CursorON.gif

Doing the install

You know the drill. We're just zooming through the Gentoo Handbook now, doing everything in a standard way. Refer to the handbook itself for reminders of things you may want to do differently, although I mention a few as we go.

Updating portage

gentoo ~#
emerge --syncImage:CursorOFF.gif

Optional: Selecting a different default profile

Just a reminder this is a good time to do this, eg:

gentoo ~#
ln -snf /usr/portage/profiles/<profile name> /etc/make.profileImage:CursorOFF.gif

Get up to date

We might as well get up to date sooner rather than later. At the time of writing 2007.1 was the current Gentoo version, and the leap up from that to up to date is quite large. In particular, you need to update portage first.

gentoo ~#
emerge -av portageImage:CursorOFF.gif
gentoo ~#
emerge -avND worldImage:CursorOFF.gif

If it looks sane, go ahead, if it doesn't, fix USE flags, whatever, as per any Gentoo system, and try again until it's right, then let it do its thing.

Timezone

gentoo ~#
cp /usr/share/zoneinfo/<timezone> /etc/localtimeImage:CursorOFF.gif
gentoo ~#
nano -w /etc/conf.d/clockImage:CursorOFF.gif

Set the timezone so things are happy.

Kernel

Naturally we do nothing at all with the kernel. We're running in a chroot; we can have everything else our own way, but we're stuck with the host's kernel.

If the host's kernel is especially old you may want to force a particular version of linux-headers in /etc/portage/package.mask to match. eg:

gentoo ~#
echo '>sys-kernel/linux-headers-2.6.18' >> /etc/portage/package.maskImage:CursorOFF.gif

Otherwise we just skip ahead to...

Filesystem information

To start with we don't need anything here. But we need a sane fstab, so

gentoo ~#
nano -w /etc/fstabImage:CursorOFF.gif

Comment out or delete everything. We start out with nothing uncommented in this file.

Later on we're going to be modifying /etc/init.d/localmount to take out its stuff where it mounts usb filesystems and so forth, but we're leaving in the part where it runs mount -a against /etc/fstab so that's available should it become useful. (I haven't tested actually doing that though: I haven't needed it.)

Hostname

For the avoidance of confusion, as /etc/init.d/hostname will get run later, set the hostname to be the same as that of the host, in /etc/conf.d/hostname.

Likewise put something sane in /etc/hosts

gentoo ~#
nano -w /etc/conf.d/hostnameImage:CursorOFF.gif
gentoo ~#
nano -w /etc/hostsImage:CursorOFF.gif

Networks

For now, don't do anything with networks. In theory you can presumably bring up additional interfaces that the host never set up for itself here; but I haven't tried it, and we don't need it to get going.

Root password

If you want to set a root password (I prefer not to, and to use sudo instead), now's the time to do it:

gentoo ~#
passwdImage:CursorOFF.gif

Creating a user

Otherwise now's the time to create a user. It's probably desirable to create this user with the same uid as your user on the host system.

gentoo ~#
useradd -m -g <username> -G wheel <username>Image:CursorOFF.gif
gentoo ~#
passwd <username>Image:CursorOFF.gif
gentoo ~#
emerge -av sudoImage:CursorOFF.gif
gentoo ~#
visudoImage:CursorOFF.gif

Allow wheel to execute root commands (or whatever is your preference).

The idea is that your normal way into using the system isn't by executing a chroot from the host, but by logging in via the network. Probably the most convenient way is to use openssh.

gentoo ~#
emerge -av opensshImage:CursorOFF.gif
gentoo ~#
nano -w /etc/ssh/sshd_configImage:CursorOFF.gif

Change the Port option to something other than that which the host system is using. I use 222, for example.

gentoo ~#
rc-update add sshd defaultImage:CursorOFF.gif

Installing necessary system tools

For now we'll install a standard logger. In fact for anything remotely production you may want to get smart here and interact with the host system's syslogd.

gentoo ~#
emerge -av syslog-ng vixie-cronImage:CursorOFF.gif
gentoo ~#
rc-update add syslog-ng defaultImage:CursorOFF.gif
gentoo ~#
rc-update add vixie-cron defaultImage:CursorOFF.gif

We're not going to start them yet though.

Making it safe

We now have an almost complete base Gentoo system. We're not setting up a kernel, of course; we're not setting up a bootloader, of course; but we do want to have a rudimentary system of runlevels so we can run our init scripts.

However, some of them could cause chaos to the host system; trying to remount / as read-only, to do an fsck, for instance, or rebooting, and so forth.

So we're going to disable most of the stuff in /etc/runlevels/boot

gentoo ~#
cd /etc/runlevels/bootImage:CursorOFF.gif
gentoo ~#
rc-update del bootmisc bootImage:CursorOFF.gif
gentoo ~#
rc-update del checkroot bootImage:CursorOFF.gif
gentoo ~#
rc-update del consolefont bootImage:CursorOFF.gif
gentoo ~#
rc-update del keymaps bootImage:CursorOFF.gif
gentoo ~#
rc-update del modules bootImage:CursorOFF.gif
gentoo ~#
rc-update del rmnologin bootImage:CursorOFF.gif
gentoo ~#
rc-update del checkfs bootImage:CursorOFF.gif
gentoo ~#
rc-update del clock bootImage:CursorOFF.gif
gentoo ~#
rc-update del hostname bootImage:CursorOFF.gif
gentoo ~#
rc-update del net.lo bootImage:CursorOFF.gif
gentoo ~#
rc-update del urandom bootImage:CursorOFF.gif

In fact, lose everything but /etc/runlevels/boot/localmount. Edit that.

gentoo ~#
nano -w /etc/init.d/localmountImage:CursorOFF.gif
  1. Delete the "depend()" section
  2. Delete everything between (non-inclusive) "Some local filesystem failed to mount" and "Activating (possible) swap"

Neither of those will do anything because we have nothing in /etc/fstab, but it's conceivable you might want to do stuff there in future.

Save and exit.

Also remove the "depend()" section from each of the following.

gentoo ~#
nano -w /etc/init.d/clockImage:CursorOFF.gif
gentoo ~#
nano -w /etc/init.d/hostnameImage:CursorOFF.gif

Having done all this it should now be safe for you to start any services you want running now, eg: sshd so you can log in as your own user.

But we'll go on into our nearest equivalent of a bootloader.

Making it start and stop

There are two aspects to this; we want to initialise the gentoo system from the host, and inside the Gentoo system we want to run any required init scripts. The reverse applies for shutting down.

FIXME: These scripts are rudimentary. The in-gentoo ones should be a single Gentoo init script, I think. The ones that run on the host probably want to be an init script for the host system as well. But for now all I have are the ones I quickly knocked up to get it working. Having /proc and /dev mounted may also be unnecessary for most purposes; I'm not sure.

Host-side start script

host ~#
vi ~/gentoo-start.shImage:CursorOFF.gif

This is mine, for example. As well as adding /proc and /dev we also mount -o bind any other parts of the host filesystem we want to see inside Gentoo.

Code: Host-side start script
 #!/bin/bash
 
 GENTOO=/mnt/md0/gentoo
 
 if [ -f ${GENTOO}/started ] ; then
 	echo "Gentoo subsystem already started."
 	exit 1
 fi
 
 echo -n "Mounting proc"
 mount -t proc none ${GENTOO}/proc
 echo "."
 
 echo -n "Mounting dev"
 mount -o bind /dev ${GENTOO}/dev
 echo "."
 
 # add any others needed
 mount -o bind /mnt/md0/vault ${GENTOO}/vault
 
 # in we go
 echo "Running Gentoo init scripts"
 chroot $GENTOO /start.sh
 
 echo "Gentoo subsystem started."
 

When you run this, the mount points will be mounted and the Gentoo-side start script will run, which runs the runlevel scripts in a pretty rudimentary fashion, then exits. So when this script exits you're not in the chroot environment; you've just "started" it.

Host-side stop script

host ~#
vi ~/gentoo-start.shImage:CursorOFF.gif
Code: Host-side stop script
 #!/bin/bash
 
 GENTOO=/mnt/md0/gentoo
 
 if [ ! -f ${GENTOO}/started ] ; then
 	echo "Gentoo subsystem hasn't been started."
 	exit 1
 fi
 
 echo "Running Gentoo's init stop scripts"
 chroot $GENTOO /stop.sh
 echo "Gentoo services stopped."
 
 echo -n "Unmounting proc"
 umount ${GENTOO}/proc
 echo "."
 
 echo -n "Unmounting dev"
 umount ${GENTOO}/dev
 echo "."
 
 # add any others needed
 
 umount ${GENTOO}/vault
 
 echo "Gentoo subsystem stopped."
 

Gentoo-side start script

Code: Gentoo-side start script /start.sh
 #!/bin/bash
 
 for BOOT in /etc/runlevels/boot/* ; do
 	$BOOT start
 done
 
 for DEF in /etc/runlevels/default/* ; do
 	$DEF start
 done
 
 touch /started
 

Gentoo-side stop script

Code: Gentoo-side stop script /stop.sh
 #!/bin/bash
 
 for DEF in /etc/runlevels/default/* ; do
         $DEF stop
 done
 
 for BOOT in /etc/runlevels/boot/* ; do
 	$BOOT stop
 done
 
 rm /started
 

It's done. Start it and log into it (if you set up sshd, for instance) and use it, install stuff... Be reasonable; it is only a chroot, and it's for running stuff that isn't going to actually mess about with the underlying system.


Last modified: Fri, 05 Sep 2008 23:38:00 +0000 Hits: 3,118