From patchwork Mon Jan 14 21:36:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 211933 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id AEDED2C00A2 for ; Tue, 15 Jan 2013 08:37:15 +1100 (EST) Received: from localhost ([::1]:39905 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TuriT-00071v-T6 for incoming@patchwork.ozlabs.org; Mon, 14 Jan 2013 16:37:13 -0500 Received: from eggs.gnu.org ([208.118.235.92]:34968) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TuriJ-00071e-F9 for qemu-devel@nongnu.org; Mon, 14 Jan 2013 16:37:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TuriH-0006w1-Co for qemu-devel@nongnu.org; Mon, 14 Jan 2013 16:37:03 -0500 Received: from smtp6-g21.free.fr ([2a01:e0c:1:1599::15]:37190) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TuriG-0006um-MF for qemu-devel@nongnu.org; Mon, 14 Jan 2013 16:37:01 -0500 Received: from localhost.localdomain (unknown [78.238.229.36]) by smtp6-g21.free.fr (Postfix) with ESMTP id 822458228F; Mon, 14 Jan 2013 22:36:53 +0100 (CET) From: Laurent Vivier To: qemu-devel@nongnu.org Date: Mon, 14 Jan 2013 22:36:49 +0100 Message-Id: <1358199410-19033-1-git-send-email-laurent@vivier.eu> X-Mailer: git-send-email 1.7.10.4 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a01:e0c:1:1599::15 Cc: Riku Voipio , Laurent Vivier Subject: [Qemu-devel] [PATCH] linux-user: Some scripts to create linux container using qemu-linux-user. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org * sudo qemu-update-binfmt.sh Call update-binfmts to install /bin/qemu- as the binfmt interpreter. * sudo qemu-create-lxc.sh This script mixes linux container, binfmt and qemu to create hybrid linux container : container on an host kernel. It will create "light" emulated virtual machine with several steps : - create a linux-user qemu- - define it as the binfmt interpreter (using qemu-update-binfmt.sh). - install a base debian system under /containers/ using debootstrap. and set a minimal configuration. - define a linux container Then you can start the container using : sudo lxc-start -n virt TARGETS STATUS: alpha: cannot run debootstrap --second stage*, but chroot is usable m68k: need patches from qemu-m68k, after that, all is working fine. mips: container can be started, but console login hangs. ppc: works fine* sparc: cannot run debootstrap --second stage (cannot fork) raspberrypi: (=armhf+raspbian) works* * needs patches I sent to the mailing-list previously Signed-off-by: Laurent Vivier --- scripts/qemu-create-lxc.sh | 280 ++++++++++++++++++++++++++++++++++++++++++++ scripts/qemu-update-binfmt | 60 ++++++++++ 2 files changed, 340 insertions(+) create mode 100755 scripts/qemu-create-lxc.sh create mode 100755 scripts/qemu-update-binfmt diff --git a/scripts/qemu-create-lxc.sh b/scripts/qemu-create-lxc.sh new file mode 100755 index 0000000..c6023de --- /dev/null +++ b/scripts/qemu-create-lxc.sh @@ -0,0 +1,280 @@ +QEMU_PATH=$(dirname $(dirname $(readlink -f $0))) + +TARGET_LIST="i386 m68k alpha sparc mips ppc raspberrypi" + +set_i386() { + : nothing specific +} + +set_m68k() { + DEBIAN_REPO=http://archive.debian.org/debian + DEBIAN_DIST=etch-m68k + DEBIAN_SIGN=55BE302B + + CONFIGURE_PARAMS=--m68k-default-cpu=m68040 +} + +set_alpha() { + DEBIAN_REPO=http://archive.debian.org/debian + DEBIAN_DIST=lenny +} + +set_sparc() { + QEMU_TARGET=sparc32plus +} + +set_mips() { + : nothing specific +} + +set_ppc() { + DEBIAN_TARGET=powerpc +} + +set_raspberrypi() { + DEBIAN_REPO=http://archive.raspbian.org/raspbian + DEBIAN_DIST=wheezy + DEBIAN_SIGN="" + DEBIAN_TARGET=armhf + QEMU_TARGET=arm +} + +check_target() { + found=0 + for available in $TARGET_LIST + do + if [ "$available" = "$TARGET" ] + then + found=1 + break; + fi + done + if [ $found -eq 0 ] + then + echo "ERROR: unknown target $TARGET" 1>&2 + exit 1 + fi + + # generic values + + CONTAINER_NAME=virt${TARGET} + CONTAINER_PATH=/containers/${TARGET} + LXC_CONF=$HOME/lxc-${TARGET}.conf + + DEBIAN_REPO=http://ftp.debian.org/debian + DEBIAN_DIST=stable + DEBIAN_SIGN="" + DEBIAN_TARGET=$TARGET + + QEMU_TARGET=$TARGET + + CHECK_BIN=check_default + + # target specific values + + set_$TARGET + + QEMU_BIN=${QEMU_PATH}/build-${QEMU_TARGET}/${QEMU_TARGET}-linux-user/qemu-${QEMU_TARGET} +} + +check_m68k() { + if ${QEMU_BIN} -cpu help | grep -q ">m68040" + then + echo "Found an existing qemu-m68k, use it !" 1>&2 + return 0 + fi + echo "Found an existing qemu-m68k, but with no m68040 emulation" 1>&2 + echo "Please, remove it" 1>&2 + echo "m68040 emulation is available from " 1>&2 + echo "git clone git://gitorious.org/qemu-m68k/qemu-m68k.git" + exit 1 +} + +check_default() { + test -e ${QEMU_BIN} +} + +installed_dpkg() { + dpkg --status "$1" > /dev/null 2>&1 +} + +check_env() { + if [ ! -e /etc/debian_version ] + then + echo "ERROR: this script works only on Debian based distro" 1>&2 + exit 1 + fi + for pkg in zlib1g gcc make debootstrap lxc + do + if ! installed_dpkg $pkg + then + echo "ERROR: $pkg is needed" 1>&2 + exit 1 + fi + done +} + +create_qemu() { + if [ -e "${QEMU_BIN}" ] + then + if ${CHECK_BIN} + then + return 0 + fi + fi + echo "cd ${QEMU_PATH} && \ + mkdir build-${QEMU_TARGET} && \ + cd build-${QEMU_TARGET} && \ + ../configure --static ${CONFIGURE_PARAMS} \ + --target-list=${QEMU_TARGET}-linux-user && \ + make" | sudo -i -u ${SUDO_USER} + if ! ${CHECK_BIN} + then + echo "ERROR: generated qemu binary is invalid !" 1>&2 + exit 1 + fi +} + +create_root() { + # sanity check + + if [ $(readlink -f ${CONTAINER_PATH}/) = "/" ] + then + echo "ERROR: invalid path ${CONTAINER_PATH}" 1>&2 + exit 1 + fi + + # check directory + + if [ -e "${CONTAINER_PATH}" ] + then + echo "${CONTAINER_PATH} already exists" 1>&2 + echo "Please, remove it" 1>&2 + exit 1 + fi + + # Debian bootstrap + + mkdir -p "${CONTAINER_PATH}" + debootstrap --foreign \ + --arch=${DEBIAN_TARGET} \ + ${DEBIAN_DIST} ${CONTAINER_PATH} \ + ${DEBIAN_REPO} && \ + + # adding qemu binary + + cp ${QEMU_BIN} ${CONTAINER_PATH}/bin && \ + ${QEMU_PATH}/scripts/qemu-update-binfmt ${QEMU_TARGET} + + # debian bootstrap second stage + + chroot ${CONTAINER_PATH} debootstrap/debootstrap --second-stage + + # configuration + + cat >> ${CONTAINER_PATH}/etc/fstab < +proc /proc proc nodev,noexec,nosuid 0 1 +devpts /dev/pts devpts nodev,noexec,nosuid 0 1 +!EOF + + echo "$CONTAINER_NAME" > ${CONTAINER_PATH}/etc/hostname + echo "c:2345:respawn:/sbin/getty 38400 console" >> ${CONTAINER_PATH}/etc/inittab + + cat >> ${CONTAINER_PATH}/etc/network/interfaces <> ${CONTAINER_PATH}/etc/apt/sources.list < ${LXC_CONF} <&2 + echo " Available targets are:" 1>&2 + echo " $TARGET_LIST" + exit 1 +fi + + +check_env +check_target + +echo "DEBIAN_TARGET : ${DEBIAN_TARGET}" +echo "QEMU_TARGET : ${QEMU_TARGET}" +echo "CONTAINER_NAME: ${CONTAINER_NAME}" +echo "CONTAINER_PATH: ${CONTAINER_PATH}" +echo "QEMU_PATH : ${QEMU_PATH}" +echo "LXC_CONF : ${LXC_CONF}" +echo "DEBIAN_REPO : ${DEBIAN_REPO}" +echo "DEBIAN_DIST : ${DEBIAN_DIST}" + +if lxc-list | grep -q ${CONTAINER_NAME} +then + echo "${CONTAINER_NAME} already exists !" 1>&2 + echo "you can remove it with :" 1>&2 + echo " sudo lxc-destroy -n ${CONTAINER_NAME}" 1>&2 + echo "[WARNING: this will remove the directory too]" 1>&2 + exit 2 +fi + +if [ "$USER" != "root" ] +then + echo "You need to be root to run this command" 2>&1 + exit 3 +fi + +create_qemu +create_root +create_lxc + +chroot ${CONTAINER_PATH} uname -a + +echo "you can now start your container using:" +echo " sudo lxc-start -n ${CONTAINER_NAME}" diff --git a/scripts/qemu-update-binfmt b/scripts/qemu-update-binfmt new file mode 100755 index 0000000..ebdd971 --- /dev/null +++ b/scripts/qemu-update-binfmt @@ -0,0 +1,60 @@ +#!/bin/bash + +name="$1" + +# probe cpu type +cpu=`uname -m` +case "$cpu" in + i386|i486|i586|i686|i86pc|BePC|x86_64) + cpu="i386" + ;; + mips*) + cpu="mips" + ;; + "Power Macintosh"|ppc64) + cpu="ppc" + ;; + armv[4-9]*) + cpu="arm" + ;; +esac + +if [ "$name" = "$cpu" ] +then + exit 0 +fi + +case $name +in + m68k) + magic="\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04" + mask="\xff\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff" + ;; + alpha) + magic="\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90" + mask="\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff" + ;; + sparc32plus) + magic="\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12" + mask="\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff" + ;; + mips) + magic="\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08" + mask="\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff" + ;; + ppc) + magic="\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14" + mask="\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff" + ;; + arm) + magic="\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00" + mask="\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff" + ;; + *) + echo "ERROR: unknown target $name" 1<&2 + exit 1 + ;; +esac + +update-binfmts --install $name /bin/qemu-${name} \ + --magic $magic --mask $mask