Gentoo 32-bit chroot environment on amd64 no-multilib


Please note that this blog has been moved.

Now it has its own domain: mynixworld.info🙂

If you want to read the latest version of this article (recommended) please click here and I open the page for you.

I have a Gentoo amd64 no-multilib configuration and sometimes I really need to run 32-bit application (Skype or Android SDK that are available only for 32bit environment).

For these I have prepared a 32-bit chroot-ed environment as specified in 32Bit Chroot Guide for Gentoo/AMD64.

Inside the 32-bit chroot environment I want to use the XServer with Xfce desktop enviroment. To make sure I will have a basic Xfce environment as I already have in the amd64 environment, I just copied the /etc/make.conf file to /mnt/gentoo32/etc/make.conf and I have adjust few options (tunned for my 32-bit virtual enviroment):

# These settings were set by the catalyst build script that automatically
# built this stage.
# Please consult /usr/share/portage/config/make.conf.example for a more
# detailed example.

# compiler optimization
CFLAGS="-O2 -pipe -march=native -mtune=native -fomit-frame-pointer -fno-var-tracking"
CXXFLAGS="${CFLAGS}"
LDFLAGS="-Wl,-O1 -Wl,--as-needed"

# parallel build & gcc cache
MAKEOPTS="-j2"
CCACHE_DIR="/var/tmp/ccache"
CCACHE_SIZE="1G"
FEATURES="parallel-fetch userfetch ccache candy compress-build-logs"

# WARNING: Changing your CHOST is not something that should be done lightly.
# Please consult http://www.gentoo.org/doc/en/change-chost.xml before changing.
CHOST="i686-pc-linux-gnu"
ACCEPT_KEYWORDS="x86"
LINGUAS="en"

# use the following gentoo repository servers:
GENTOO_MIRRORS="http://mirror.mdfnet.se/gentoo"
SYNC="rsync://rsync.se.gentoo.org/gentoo-portage"

# by default we acknowledge the have the following devices
INPUT_DEVICES="keyboard mouse evdev synaptics"
VIDEO_CARDS="radeon vesa fbdev"
ALSA_CARDS="ens1370"
WEB_CAM="v4l v4l2"
APACHE2_MODULES="*-"
CAMERAS="*-"
CALLIGRA_FEATURES="*-"
GPSD_PROTOCOLS="*-"
LCD_DEVICES="*-"

# do not unmask automatically anything but accept any 3rd party license agreement
EMERGE_DEFAULT_OPTS="--autounmask=n"
ACCEPT_LICENSE="*"

# These are the USE flags that were used in addition to what is provided by the
# profile used for building.
# See: http://www.gentoo.org/dyn/use-index.xml
USE_OPTIMIZATION="optimization strong-optimization mmx pch sharedmem smp sse sse2 lto graphite optimized-qmake"
USE_SYS_KERNEL="savedconfig"
USE_SYS_LIBS="glibc-omitfp python"

USE_LAPTOP="acpi" # bluetooth"
USE_X="truetype X new-login xorg"
USE_IMAGE="jpeg gif tiff png svg pdf"
USE_MEDIA="sound alsa mad vidix asf win32codecs dvd mp4 aac x264 xvid nsplugin mp3 real gstreamer"
USE_GENERAL="udev ncurses bash-completion libnotify ftp samba java bzip2 symlink sqlite threadsafe spell xml lm_sensors"
USE_SYSTEM="hal fam dbus aoss nptl threads"
USE_DONT="-arts -qt4 -ipv6 -opengl"
USE_KDE="-kde -qt3"
#USE_GNOME="gtk cairo gnome gnome-keyring archive sendto aisleriot"
USE_GNOME="-gnome -gnome-keyring"
USE_LXDE="-lxde cairo"
USE_XFACE="session startup-notification"

USE_APP_ADMIN="edit sudo custom-optimization"
USE_APP_EMULATION="consolekit"
USE_WWW_PLUGINS="32bit"
USE_X11_TERMS="mousewheel"
USE_X11_DUALMONITOR="-xinerama"
USE_X_COMPOSITE="xcomposite"
USE="${USE_DONT} ${USE_SYSTEM} ${USE_GENERAL} ${USE_IMAGE} ${USE_X} ${USE_KDE} ${USE_MEDIA} ${USE_OPTIMIZATION} ${USE_APP_ADMIN} ${USE_APP_EMULATION} ${USE_GNOME}"
USE="${USE} ${USE_SYS_KERNEL} ${USE_SYS_LIBS} ${USE_WWW_PLUGINS} ${USE_X11_DRIVERS} ${USE_X11_TERMS} ${USE_LXDE} ${USE_XFACE} ${USE_X11_DUALMONITOR} ${USE_X_COMPOSITE} ${USE_KVM} ${WEB_CAM} ${USE_LAPTOP}"

Also, I have configured the /mnt/gentoo32/etc/portage/package.use and /mnt/gentoo32/etc/portage/package.keywords configuration files with those options necessary to build my 32-bit environment:

package.use

x11-base/xorg-server udev
sys-auth/consolekit policykit
sys-apps/hal policykit
dev-libs/libxml2 python
sys-fs/udev extras
app-crypt/pinentry gtk
gnome-base/gvfs gdu
media-libs/libpng apng
app-emulation/wine custom-cflags

package.keywords

>=net-im/skype-2.2.0.35-r1
app-emulation/winetricks **

In the virtual 32-bit environment I have installed just those applications I will really need, such as:

  • app-admin/sudo
  • app-editors/nano
  • app-emulation/wine
  • app-emulation/winetricks
  • app-portage/gentoolkit
  • dev-util/ccache
  • net-im/skype
  • gnome-extra/zenity
  • x11-base/xorg-drivers
  • x11-base/xorg-server
  • x11-terms/terminal
  • xfce-base/thunar
  • xfce-base/xfce4-meta
  • xfce-extra/thunar-archive-plugin
  • xfce-extra/thunar-volman
  • xfce-extra/tumbler

For building the above 32-bit application within the chroot-ed environment just chroot inside the 32-bit environment (eg: sudo linux32 chroot /mnt/gentoo32/ /bin/bash) and run (as root) the command below:

emerge -DuN world

After several minutes/hours (this depends on your hardware) you should have a 32-bit environment with everythig that is need it for running a XServer with Xfce desktop environment.

Inside the chroot-ed environment create the following file in the home directory of <your login name> user (eg: /mnt/gentoo/<your login name>/):

.bashrc

# /etc/skel/.bashrc
#
# This file is sourced by all *interactive* bash shells on startup,
# including some apparently interactive shells such as scp and rcp
# that can't tolerate any output.  So make sure this doesn't display
# anything or bad things will happen !

# Test for an interactive shell.  There is no need to set anything
# past this point for scp and rcp, and it's important to refrain from
# outputting anything in those cases.
if [[ $- != *i* ]] ; then
# Shell is non-interactive.  Be done now!
return
fi

# Put your fun stuff here.

# if X is not started already then start your favorite X session
# otherwise just run the normal terminal (within the chroot-ed X session)
if [ -z $DISPLAY ];then
startxfce4 -- :1
exit
fi

Inside the chroot-ed environment create a file named 90xsession in the /etc/env.d/ folder:

XSESSION="Xfce4"

Now, if you issue the X command at the console within the chroot-ed environment, it should start the XServer and launch the Xfce desktop environment for you. When you logoff from the Xfce session it should return to the console within the chroot-ed environment.

Let’s automate little bit the way we get into the chroot environment and how we launch the Xfce session on that environment!

Instead of mounting/unmounting the virtual filesystem (as described in step 2.c) I have created a bash script which will help me to:

  • automatically mount the necessary folders/devices for my chroot environment virtual file system
  • copy the necessary configuration files into the chroot-ed environment (eg: resolv.conf, hosts, passwd)
  • enter to 32-bit chroot-ed environment and login as prefered user
  • start Xfce session (or whatever program from the chrooted environment) in the chroot-ed environment on display 1 (or even on the display 0), so both sessions – the amd64 default Xfce session and the newly created chroot-ed 32bit Xfce session – are available simultaneously (switch between them with Ctrl+Alt+Fn, where n could be 7,8,…); if you started just a program on current display (eg: display 0) then no switch available/need it
  • exit cleanly from chroot-ed environment and umount previously mounted folders for the virtual file system

So just launching the bash script it will create automatically for you  the chroot environment and will start a new X session on another virtual display (eg: display 1). You can, as explained above, work on both sessions, but you have to switch between them with Ctrl+Alt+Fn keys.

First create a bash script called gentoo32 as bellow:

#!/bin/bash

# Path where the chroot environment is installed
CHROOT_ENV_PATH="/mnt/gentoo32"

# Print the script help syntax
function print_syntax()
{
	echo -e "Usage : $0 [OPTION]...\nLogin to a chrooted environment as <user> then imediately run the <cmd> command on the specified <vt> display.\n"
	echo -e "Mandatory arguments to long options are mandatory for short options too.\n"
	echo -e "  -s, --service <svc>\tmount|unmount necessary folders and start|stop chroot-ed environment"
	echo -e "  -c, --command <cmd>\trun the <cmd> command immediately after loging in the chroot-ed environment"
	echo -e "  -d, --display <vt>\tthe virtual terminal used to display the <cmd> command"
	echo -e "  -u, --user <user>\tthe user used to login in the chroot-ed environment\n"
	echo "Report bugs to <eugenmihailescux@gmail.com>"
}

SHORTOPTS="s: c: d: u:"
LONGOPTS="service: command: display: user:"
set -- `getopt -a -u --options="$SHORTOPTS" --longoptions="$LONGOPTS" --name="$0" -- "$@"` || print_syntax

# Check for sufficent args
if [ $# -lt 2 ] ; then
        print_syntax
        exit 1
fi

# Read the options/arguments from command-line
while [ $# -gt 0 ];do
  case $1 in
    -s|--service)
	SERVICE=$2;shift;;
    -c|--command)
	COMMAND=$2;shift;;
    -d|--display)
	VT=$2;shift;;
    -u|--user)
	CHROOT_USR=$2;shift;;
    \?)	echo "Invalid option: -$1";
	print_syntax;
	exit 1;
 	;;
   🙂
	echo "Option -$1 requires an argument.";
	print_syntax;
	exit 1;
	;;
    -h) print_syntax;;
    --) shift;break;;
    -*) print_syntax;;
     *) break;;
  esac
  shift
done

# Set terminal title
# @param string $1  Tab/window title
# @param string $2  (optional) Separate window title
# The latest version of this function can be obtained here:
# http://fvue.nl/wiki/NameTerminal
function nameTerminal() {
    [ "${TERM:0:5}" = "xterm" ]   && local ansiNrTab=0
    [ "$TERM"       = "rxvt" ]    && local ansiNrTab=61
    [ "$TERM"       = "konsole" ] && local ansiNrTab=30 ansiNrWindow=0
        # Change tab title
    [ $ansiNrTab ] && echo -n $'\e'"]$ansiNrTab;$1"$'\a'
        # If terminal support separate window title, change window title as well
    [ $ansiNrWindow -a "$2" ] && echo -n $'\e'"]$ansiNrWindow;$2"$'\a'
}

# Terminal title
nameTerminal "32bit chroot enviroment"

# Create a .bashrc file on the home directory of chrooted user ${CHROOT_USR}
# This .bashrc file is prepared to run the command <cmd> on display <vt>
function prepare_bashrc(){
        # Replace &nbsp; and &quot; in <cmd> with a space respectively with double quote
        # Note: you can specify &nbsp; in your <cmd> instead of <space> ASCII,
        # the script will convert it to ASCII space at runtime
        startup_app=$(echo $1|awk '{p=gsub(/&nbsp;/, " ");gsub(/&quot;/, "\""); print}')
	display=$2
	bashrc_path="${CHROOT_ENV_PATH}/home/${CHROOT_USR}/.bashrc"
	echo "#Automatically created by $0"  > ${bashrc_path}
	echo "if [[ \$- != *i* ]] ; then" >> ${bashrc_path}
	echo "	return" >> ${bashrc_path}
	echo "fi" >> ${bashrc_path}
	echo "if [ -z \$DISPLAY ];then" >> ${bashrc_path}
	if [ "${display}" != "" ];then
		echo "	export DISPLAY=":${display}"" >> ${bashrc_path}
	fi
	echo "	${startup_app}" >> ${bashrc_path}
        echo "	exit" >> ${bashrc_path}
	echo "fi" >> ${bashrc_path}
	chown ${CHROOT_USR}:${CHROOT_USR} ${bashrc_path}
}

start() {
    echo -e "\E[1;31m[1] Mounting chroot dirs...\033[0m"

    # MANDATORY : bind the local system folders to the corresponding folders inside the chrooted environment
    mount -o bind /proc ${CHROOT_ENV_PATH}/proc
    mount -o bind /sys ${CHROOT_ENV_PATH}/sys
    mount -o bind /tmp ${CHROOT_ENV_PATH}/tmp
    mount -o bind /dev ${CHROOT_ENV_PATH}/dev
    mount -o bind /dev/pts ${CHROOT_ENV_PATH}/dev/pts
    mount -o bind /dev/shm ${CHROOT_ENV_PATH}/dev/shm

    # OPTIONAL : bind the local user folders to the corresponding folders inside the chrooted environment
    mount -o bind /home/myuser/svn ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/svn 2>/dev/null
    mount -o bind /home/myuser/workspace.eclipse/java ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/workspace/java/ 2>/dev/null
    echo -e "\E[1;32m[1] Done.\033[0m"

    # MANDATORY : copy the local system security files/settings to the corresponding files inside the chrooted environment
    echo -e "\E[1;31m[2] Copying neccessary files for chrooted environment...\033[0m"
    cp -pf /etc/resolv.conf ${CHROOT_ENV_PATH}/etc 2>/dev/null
    cp -pf /etc/passwd ${CHROOT_ENV_PATH}/etc 2>/dev/null
    cp -pf /etc/shadow ${CHROOT_ENV_PATH}/etc 2>/dev/null
    cp -pf /etc/group ${CHROOT_ENV_PATH}/etc 2>/dev/null
    cp -pf /etc/gshadow ${CHROOT_ENV_PATH}/etc 2>/dev/null
    cp -pf /etc/hosts ${CHROOT_ENV_PATH}/etc 2>/dev/null
    cp -Ppf /etc/localtime ${CHROOT_ENV_PATH}/etc 2>/dev/null
    echo -e "\E[1;32m[2] Done.\033[0m"
}

# Function for unmounting the
stop() {
    echo -e "\E[1;31m[*] Unmounting chrooted dirs...\033[0m"
    # MANDATORY : unmount the chrooted environment system folder bindings
    umount -l ${CHROOT_ENV_PATH}/dev/{pts,shm}
    umount -l ${CHROOT_ENV_PATH}/{dev,proc,sys,tmp}

    # OPTIONAL : unmount the chrooted environment user folder bindings
    umount -l ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/workspace/java
    umount -l ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/svn
    echo -e "\E[1;32m[*] Done.\033[0m"
}

# Switch to root profile if running as normal user
if [ "$(whoami)" != "root" ]; then
	echo -e "\E[1;34m"
	params=""
	if [ "${SERVICE}" != "" ];then
		params+=" -s ${SERVICE}"
	fi
        if [ "${COMMAND}" != "" ];then
                params+=" -c ${COMMAND}"
        fi
        if [ "${VT}" != "" ];then
                params+=" -d ${VT}"
        fi
        if [ "${CHROOT_USR}" != "" ];then
                params+=" -u ${CHROOT_USR}"
        fi

        sudo -p "Enter root password for entering into chrooted environment : " -u root $0 ${params}
	echo -e "\033[0m"
        err=$?
	exit $err
else
        ${SERVICE}
	err=0
fi

# Run the chrooted environment, login to it as <user> then run the <cmd> on display <vt>
if [ "$err" == "0" ];then
        if [ "$SERVICE" == "start" ];then
		echo -e "\E[1;31m[3] Entering to chroot environment...\033[0m"
		prepare_bashrc "${COMMAND}" "${VT}"
		linux32 chroot ${CHROOT_ENV_PATH} /bin/bash -c "echo -e 'Login as \E[1;35m${CHROOT_USR}\033[0m within \E[1;34mchroot-ed\033[0m environment...' && login ${CHROOT_USR}"
		echo -e "\E[1;32m[4] Exited from chroot environment.\033[0m"
		stop
        fi
fi

Note: in the above script (1) </mnt/gentoo32> should be your linux folder where you have installed the chrooted environment.

When you will run the above script it will ask you for root password (mount requires root authentification), will open automatically the 32-bit chroot-ed environment, will ask you the password for the <your login name> and then will launch Xfce session for you. When you will logoff from the X session within the chroot-ed environment, the same script will take care of exiting from the chroot-ed environment, unmounting previously mounted folders. So everything is lean and clean…

Usage : /usr/sbin/gentoo32 [OPTION]...
Login to a chrooted environment as  then imediately run the  command on the specified  display.

Mandatory arguments to long options are mandatory for short options too.

-s, --service     mount|unmount necessary folders and start|stop chroot-ed environment
-c, --command     run the  command immediately after loging in the chroot-ed environment
-d, --display     the virtual terminal used to display the  command
-u, --user     the user used to login in the chroot-ed environment

Report bugs to

Examples:

  • launch Xfce session in the chrooted environment:

gentoo32 –service=start –command=”startxfce4&nbsp;–&nbsp;:1″ –user=myname

  • launch Eclipse application without starting a separate 32-bit Xfce session, on the same display (eg: display 0) as the main Xfce 64-bit session:

gentoo32 –service=start –command=”eclipse” -d 0 –user=myname

  • launch Skype application without starting a separate 32-bit Xfce session, on the same display (eg: display 0) as the main Xfce 64-bit session:

gentoo32 –service=start –command=”skype” -d 0 –user=myname

About Eugen Mihailescu

Always looking to learn more about *nix world, about the fundamental concepts of arithmetic, algebra and geometry. I am also passionate about programming, database and systems administration.
This entry was posted in linux and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s