Gentoo Logo
Gentoo Spaceship

Note: Due to technical difficulties, the Archives are currently not up to date. GMANE provides an alternative service for most mailing lists.
c.f. bug 424647
List Archive: gentoo-amd64
Lists: gentoo-amd64: < Prev By Thread Next > < Prev By Date Next >
To: gentoo-amd64@g.o
From: Barry.SCHWARTZ@...
Subject: Re: chroot howto?
Date: Wed, 13 Jul 2005 05:05:51 -0500
Peter Humphrey <prh@...> wrote:
> I unpacked an x86 stage 3, and set up hosts, networks and users as
> instructed, but when I tried "linux32 chroot /mnt/gentoo32 /bin/bash" I
> got a permission-refused error on /bin/bash. (I tried both with and
> without --login; it made no difference.)

Did you do this as root?

> So I unpacked a portage
> snapshot, rebooted from the installation CD and tried again. I could
> then chroot. I reasoned that /bin/bash could not be executed because
> there was no 32-bit kernel, so I emerged and compiled gentoo-sources in
> /mnt/gentoo32. After that I could chroot from the installed system.

You don't need a 32-bit kernel.  For a few things it can be convenient
to have kernel sources present, but I don't remember what things those
are.  Cross that bridge if you come to it.

> But how much more of a Gentoo system do I need to build in the chroot
> jail? Emerge --sync? Emerge system? I have /mnt/tmp bound to
> /mnt/gentoo32/mnt/tmp, and /mnt/home, /mnt/boot, /mnt/usr/share and
> /mnt/usr/portage/distfiles bound similarly. Do I need to env-update
> whenever I chroot? What difference is there between chroot with and
> without --login, apart from sourcing /etc/profile etc?

I set up my own init script that uses 'mount --bind' to mount and
unmount things that you need inside the chroot.  So that happens at

As far as getting into the chroot, if I am root I do it with a Perl script:

#!/usr/bin/perl -wT

$root_32bit = "/gentoo32"; # The root directory of the 32-bit environment.

$ENV{PATH} = '/bin:/usr/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

$#ARGV == -1 or die "$0: Does not accept arguments\n";

# su to oneself.  Non-root users may be asked for their password.
# (We require that the user name begin with an alphabetic character
# and consist only of alphanumeric characters.)
$user = getpwuid($<);
$user =~ /^([[:alpha:]][[:alnum:]]*)$/
    or die "$0: \"$user\" doesn't look like a user name to me\n";
$user = $1;
exec "linux32", "chroot", "$root_32bit", "su", "-", "$user";

die "$0: $!\n";

If I am non-root I do it with a simple suid root C program that is
adapted from linux32.

/* $Id: l32.c,v 1.3 2004/08/18 05:09:30 trashman Exp $ */

#include <linux/personality.h>
#undef personality
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>

long int personality(unsigned long int persona);

/* Restrict address space to 3 GB, for the sake of buggy Java. */
const unsigned long int default_personality = PER_LINUX32_3GB;
const char *const gentoo32 = "/gentoo32";

int main(int argc, char *argv[], char *envp[] __attribute__((unused)))
    int result;
    long int long_result;
    unsigned long int pers;
    char *cwd;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s COMMAND [ARG]...\n", argv[0]);

    pers = default_personality;

    cwd = getcwd(NULL, 0);      /* Linux-specific: allocate as many
                                 * bytes as necessary. */
    if (cwd == NULL) {
        fprintf(stderr, "Can't allocate necessary space: %s\n", strerror(errno));

    long_result = personality(pers);
    if (long_result == -1) {
        fprintf(stderr, "Can't set personality %lx: %s\n", pers, strerror(errno));

    result = chroot(gentoo32);
    if (result != 0) {
        fprintf(stderr, "Can't chroot(%s): %s\n", gentoo32, strerror(errno));

    /* Drop root privileges. */
    result = setuid(getuid());
    if (result != 0) {
        fprintf(stderr, "Can't suid(%d): %s\n", getuid(), strerror(errno));

    /* Make sure we are inside the chroot. */
    result = chdir("/");
    if (result != 0) {
        fprintf(stderr, "Can't chdir(%s) within the chroot: %s\n",
                gentoo32, strerror(errno));

    /* Change into the chroot's equivalent of the current working
     * directory. */
    result = chdir(cwd);
    if (result != 0) {
        fprintf(stderr, "Can't chdir(%s) within the chroot: %s\n",
                cwd, strerror(errno));

    execvp(argv[1], argv + 1);

    abort();                    /* We shouldn't get here. */

'l32 zsh --login' gets me a 32-bit shell.

I maintain my chroot as practically another whole system.  That's
wasteful but makes some things a lot easier -- even maintenance is
easier with all that waste, because you are letting portage 'think'
for you about what it needs to install.

I used to also run stuff like sshd inside the chroot, but don't
anymore, and I think you can ignore that.

Esperantistoj rajtas skribi al Barijo.SXVARCO@...
pgpeadIKlO0rN.pgp (PGP signature)
Re: chroot howto?
-- Peter Humphrey
chroot howto?
-- Peter Humphrey
Lists: gentoo-amd64: < Prev By Thread Next > < Prev By Date Next >
Previous by thread:
chroot howto?
Next by thread:
Re: chroot howto?
Previous by date:
tar/bzip2 not working in chroot
Next by date:
Re: chroot howto?

Updated Jun 17, 2009

Summary: Archive of the gentoo-amd64 mailing list.

Donate to support our development efforts.

Copyright 2001-2013 Gentoo Foundation, Inc. Questions, Comments? Contact us.