From 18f051d28ed039399c067852a2b7cec825838561 Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Mon, 4 Nov 2013 11:22:56 +0100 Subject: [PATCH 1/1] QEMU trick to run own system inside QEMU with root overlay and home pass-through. Signed-off-by: Pavel Pisa --- qemu-run-trick/qemu-setup-and-run | 253 ++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100755 qemu-run-trick/qemu-setup-and-run diff --git a/qemu-run-trick/qemu-setup-and-run b/qemu-run-trick/qemu-setup-and-run new file mode 100755 index 0000000..e67046b --- /dev/null +++ b/qemu-run-trick/qemu-setup-and-run @@ -0,0 +1,253 @@ +#!/bin/bash +# +# QEMU trick to dive user in his own hoe environment +# as root in a virualized shadow of his own system +# +# (C) 2013 Pavel Pisa +# +# THE TSCRIPT IS PROVIDED “AS IS” WITHOUT WARRANTY +# OF ANY KIND, EITHER EXPRESSED OR IMPLIED. +# +# There is no limitation of scrip use, modification +# and distribution or relicensing. +# +# Some used ideas are documented at CTU FEE A4M35OSP +# excercises pages +# http://support.dce.felk.cvut.cz/osp/cviceni/2/ +# http://support.dce.felk.cvut.cz/osp/cviceni/2-en/ +# +# and Departemnt Of Control Engineering IT Wiki +# https://support.dce.felk.cvut.cz/ +# + +QEMU=qemu-system-x86_64 +BUSYBOX=$(which busybox) +RESIZE=$(which resize) +KERNEL_VERSION=$(uname -r) +KERNEL_IMAGE=/boot/vmlinuz-${KERNEL_VERSION} +RAMDISK_ARCHIVE=ramdisk.cpio +#GEN_INIT_CPIO=$(dirname $0)/gen_init_cpio +INITRD_DIR=initrd_content +MODULES_LIST="virtio virtio_ring virtio_pci virtio_net virtio_net fscache 9pnet 9pnet_virtio 9p aufs" +QEMU_MEMORY="-m 1024" +QEMU_KVM_ENABLE="-enable-kvm" +#QEMU_OUTPUT="-vga cirrus -serial null" +QEMU_OUTPUT="-nographic -append console=ttyS0" + +INITRD_DIR_ABS=$(readlink -f ${INITRD_DIR}) + +function libraries_for_binary() +{ + ldd $1 | sed -n -e 's#^\t\(/[^ ]*\) .*$#\1#p' -e 's#^\t\([^ ]*\) => \([^ ]\+\) .*$#\2#p' +} + +function deep_copy() +{ + src=$1 + tgt_dir=$2 + + while true ; do + mkdir -p ${tgt_dir}/$(dirname ${src}) || return 1 + cp -av ${src} ${tgt_dir}/${src#/} || return 1 + + l=$(readlink ${src}) + if [ -z "$l" ] ; then + return 0 + fi + if [ ${l:0:1} != '/' ] ; then + l=$(dirname ${src})/${l} + fi + src=${l} + done +} + +function setup_initrd_content() +{ + mkdir -p ${INITRD_DIR_ABS} + mkdir -p ${INITRD_DIR_ABS}/bin + mkdir -p ${INITRD_DIR_ABS}/etc/init.d + + LIBS=$(libraries_for_binary ${BUSYBOX}) + if [ -n "${RESIZE}" ] ; then + LIBS+=" "$(libraries_for_binary ${RESIZE}) + fi + + LIBS="$(for i in ${LIBS} ; do echo $i ; done | sort -u)" + + for i in ${LIBS}; do + deep_copy ${i} ${INITRD_DIR_ABS} + done + + cp -a ${BUSYBOX} ${INITRD_DIR_ABS}/bin + ( cd ${INITRD_DIR_ABS}/bin && ln -s busybox sh ) + + if [ -n "${RESIZE}" ] ; then + cp -a ${RESIZE} ${INITRD_DIR_ABS}/bin + fi + + + for m in ${MODULES_LIST} ; do + mf=$(find /lib/modules/${KERNEL_VERSION} -name ${m}.ko ) + if [ -n ${mf} ] ; then + mkdir -p ${INITRD_DIR_ABS}/$(dirname ${mf}) + cp -a ${mf} ${INITRD_DIR_ABS}/${mf#/} + fi + done + + rootmnt=/mnt/root + init=/sbin/init + root_dir_list="/proc /sys /dev /mnt /mnt/root /mnt/rootbase /mnt/overlay /tmp" + + ( + echo '#!/bin/sh' + for d in $root_dir_list ; do + echo "mkdir -p $d" + done + + cat </tmp/term-size + . /tmp/term-size + stty cols \$COLUMNS rows \$LINES + rm -f /dev/tty + mv /dev/tty-backup /dev/tty +fi +mount -t 9p -o ro,trans=virtio root /mnt/rootbase +mount -t tmpfs overlay /mnt/overlay +mount -n -t aufs -o dirs=/mnt/overlay=rw:/mnt/rootbase=ro unionfs ${rootmnt} +mount -n -o move /dev ${rootmnt}/dev +mount -n -o move /sys ${rootmnt}/sys +mount -n -o move /proc ${rootmnt}/proc +mount -t 9p -o trans=virtio home ${rootmnt}/home +mount -t tmpfs none ${rootmnt}/root +mount -t tmpfs none ${rootmnt}/tmp +mount -t tmpfs none ${rootmnt}/run +mount -t tmpfs none ${rootmnt}/var/log +mount -t tmpfs none ${rootmnt}/var/tmp + +rm ${rootmnt}/var/lib/urandom/random-seed +rm -rf ${rootmnt}/etc/shadow +echo >${rootmnt}/etc/shadow +rm -rf ${rootmnt}/etc/ssh +mkdir ${rootmnt}/etc/ssh + +rm -f ${rootmnt}/etc/rc2.d/* ${rootmnt}/etc/rc3.d/* ${rootmnt}/etc/rc4.d/* ${rootmnt}/etc/rc5.d/* + +rm -rf ${rootmnt}/etc/fstab.d ${rootmnt}/etc/fstab +echo >${rootmnt}/etc/fstab + +rm -rf ${rootmnt}/var/lib/dpkg/lock ${rootmnt}/var/lib/apt/lists/lock ${rootmnt}/var/cache/apt/archives/lock +rm -rf ${rootmnt}/etc/apt/apt.conf.d/*etckeeper ${rootmnt}/var/lib/dpkg/triggers/Lock + +rm -rf ${rootmnt}/etc/network/interfaces.d ${rootmnt}/etc/network/interfaces +echo "auto lo eth0" >${rootmnt}/etc/network/interfaces +echo "iface lo inet loopback" >>${rootmnt}/etc/network/interfaces +echo "iface eth0 inet dhcp" >>${rootmnt}/etc/network/interfaces + +if [ -e ${rootmnt}/bin/bash ] ; then + shell=/bin/bash +else + shell=/bin/sh +fi + +mv ${rootmnt}/etc/inittab ${rootmnt}/etc/inittab.orig +cp ${rootmnt}/etc/inittab.orig ${rootmnt}/etc/inittab +sed -i -e '/\/sbin\/.*getty/d' ${rootmnt}/etc/inittab +#echo "1:2345:respawn:/bin/sh" >>${rootmnt}/etc/inittab +#echo "T0:1234:respawn:/bin/sh" >>${rootmnt}/etc/inittab + +echo "1:2345:respawn:/sbin/agetty -n -l \${shell} -o '-l' tty1 38400 linux" >>${rootmnt}/etc/inittab +echo "2:23:respawn:/sbin/agetty -n -l \${shell} -o '-l' tty2 38400 linux" >>${rootmnt}/etc/inittab +echo "T0:23:respawn:/sbin/agetty -n -l \${shell} -o '-l' -L ttyS0 9600 xterm" >>${rootmnt}/etc/inittab + +exec switch_root ${rootmnt} /sbin/init +EOF + + ) >${INITRD_DIR_ABS}/init + + chmod 755 ${INITRD_DIR_ABS}/init + + return 0 +} + +function build_initrd_gen_init_cpio() +{ + + ( + cat < filelist + + $GEN_INIT_CPIO filelist | gzip > ${RAMDISK_ARCHIVE} + + return 0 +} + +function build_initrd_cpio() +{ + ( cd ${INITRD_DIR_ABS} && find . | cpio --quiet -H newc -o ) | gzip -9 > ${RAMDISK_ARCHIVE} +} + +function run_virt_system() +{ + $QEMU -enable-kvm -kernel ${KERNEL_IMAGE} \ + -initrd ${RAMDISK_ARCHIVE} ${QEMU_MEMORY} \ + -virtfs local,path=/,security_model=none,mount_tag=root \ + -virtfs local,path=/home,security_model=none,mount_tag=home \ + -net nic,macaddr=be:be:be:10:00:01,model=virtio,vlan=0 \ + -net user,vlan=0 \ + ${QEMU_KVM_ENABLE} ${QEMU_OUTPUT} + +# -chardev can,id=canbus0,port=can0 +# -device pci-can,chardev=canbus0,model=SJA1000 +# -device apohw -vga cirrus +# -device mf624,port=55555 + + return $? +} + +function clean_setup() +{ + rm -rf ${RAMDISK_ARCHIVE} filelist ${INITRD_DIR_ABS} +} + +clean_setup || exit 1 +echo "=== setup_initrd_content ===" +setup_initrd_content || exit 1 +echo "=== build_initrd ===" +if [ -n "${GEN_INIT_CPIO}" ] ; then + build_initrd_gen_init_cpio || exit 1 +else + build_initrd_cpio || exit 1 +fi +echo "=== run_virt_system ===" +run_virt_system || exit 1 -- 2.39.2