#!/bin/bash # # \brief Manage rumpkernel tools # \author Josef Soentgen # \date 2014-04-29 # # # Needed by glibc, otherwise loading modules as libraries for the # rumpkernel does not work # export LD_DYNAMIC_WEAK=1 msg() { [ $ARG_VERBOSE -ge 0 ] && printf -- "${1}\n" } debug() { [ $ARG_VERBOSE -ge 2 ] && printf -- "\t${1}\n" > /dev/stderr } trap_exit() { if [ "$RUMP_SERVER" ]; then if [ $ARG_CRYPT_DEV -ne 0 ] && [ "$ARG_CRYPT_KEY" != "" ]; then rump_client "cgdconfig" "-u cgd0" fi rump_client "halt" fi [ -d "$RUMP_TMP" ] && rm -rf $RUMP_TMP } trap_abort() { trap_exit [ -d "$RUMP_TMP" ] && rm -rf $RUMP_TMP } # # Start the rumpkernel # # \param libs list of libraries (modules) the rumpkernel should # load on start-up # \param disks list of drivespecs the rumpkernel should attach # rump_server() { local libs="$1" local disks="$2" $DRY_RUN $RUMP_PATH/rump_server $libs $disks $RUMP_SERVER if [ $? -ne 0 ]; then msg "could not start rump server." unset RUMP_SERVER exit 1 fi } # # Run a rumpkernel client # # \param cmd commando to execute within the rumpkernel # \param args arguments for the commando # rump_client() { local cmd="$1" local args="$2" debug "$RUMP_PATH/$cmd $args" $DRY_RUN $RUMP_PATH/$cmd $args if [ $? -ne 0 ]; then echo "executing '$(basename $cmd) $args' failed." # XXX kill all processes that are still haning around # exit 1 fi } # # Encrypt or decrypt device # # If the key parameter is not blank decrypt the device. Otherwise # generate a new key to encrypt. # # \param key key to encrypt # do_crypt_dev() { local key="$1" local args= if [ "$key" = "" ]; then args="-g -k storedkey -o /cgd0.conf aes-cbc 256" else args="cgd0 $RUMP_DISK_DEV /cgd0.conf" fi rump_client "cgdconfig" "$args" } # # Format file system # # \param fs file system type # \param dev raw device # do_format_fs() { local fs="$1" local dev="$2" local prog= local args= case $fs in ffs) prog="newfs";; ext2fs) prog="newfs_ext2fs"; args="-I";; *) msg "unsupported fs given."; return;; esac args="$args $dev" rump_client "$prog" "$args" } # # List files in the file system # # \param mntpt mount point of file system in the rumpkernel namespace # do_list_fs() { local mntpt="$1" rump_client "ls" "-lRah $mntpt" } # # Mount fs # # \param fs type of file system # \param dev device to mount # \param mntpt mount point # do_mount_fs() { local fs="$1" local dev="$2" local mntpt="$3" args="$dev $mntpt" # XXX maybe check if $mntpt exists rump_client "mkdir" "$mntpt" rump_client "mount_$fs" "$args" } # # Umount fs # # \param mntpt mount point # do_umount_fs() { local mntpt="$1" rump_client "umount" "$mntpt" } # # Populate fs # # \param top_dir root directory # do_populate_fs() { local top_dir="$(readlink -f $1)" local dirs="$(find $top_dir -mindepth 1 -type d|sed 's:'$top_dir'/::g')" local files="$(find $top_dir -type f|sed 's:'$top_dir'/::g')" # # First create the directories and copy the files thereafter # for dir in ${dirs[*]}; do rump_client "mkdir" "-p /mnt/$dir" done for file in ${files[*]}; do target_dir="$(dirname ${file})" rump_client "cp" "${RUMP_HOST_DIR}/${file} /mnt/${target_dir}" done } # # Create cgdconfig(8) file from given key # # \param config_file name of the output file # \param key key string # create_cgd_config() { local config_file=$1 local key=$2 if [ "$key" != "" ]; then $TOOL_DIR/rump_cgdconf -k $key > $config_file else echo > $config_file fi chmod 600 $config_file } # # Create temporary directory # # If the dir parameter is not set, create a temp directory automagically. # # \param dir path to the directory # create_temp_dir() { local dir="$1" if [ "$dir" != "" ]; then RUMP_TMP="$dir" mkdir $RUMP_TMP else RUMP_TMP=$(mktemp -d -t genode-rump.XXXXXX 2>&1) [ $? -ne 0 ] && { echo 'could not create temp dir'; exit 1; } fi } # # Print usage # print_usage() { local help="$1" printf "usage: $PROG_NAME [-cfhlnvH] [-d dev] [-F fs] [-k key] " printf "[-p dir] [-t dir] \n" if [ "$help" != "" ]; then printf "\t-c use cgd(4) to en/decrypt image\n" printf "\t-f format image (see -F)\n" printf "\t-h print this help screen\n" printf "\t-l list files in disk_image\n" printf "\t-n dry run, print commands w/o executing\n" printf "\t-v verbose mode, may be used multiple times\n" printf "\t-d dev device which is used for formatting within " printf "the rumpkernel\n" printf "\t [e.g. /blk_device or /dev/rcgd0a]\n" printf "\t-F fs specify file system [ffs, ext2fs]\n" printf "\t-k key use given key to access cgd(4) device\n" printf "\t-p dir populate the image with the content of " printf "dir\n" printf "\t-t dir temp directory for storing rump tool " printf "files [/tmp/genode-rump.XXXXXX]\n" fi } # # Parse commandline arguments # parse_arguments() { args=$(getopt cd:fhk:lnp:t:vHF: ${*}) [ $? != 0 ] && exit 1 if [ $# -lt 1 ] then print_usage exit 1 fi set -- $args while [ $# -ge 0 ]; do case "$1" in -c) ARG_CRYPT_DEV=1; shift;; -d) ARG_DISK_DEV="$2"; shift; shift;; -f) ARG_FORMAT_DEV=1; shift;; -F) ARG_FORMAT_FS="$2"; shift; shift;; -h) print_usage "help"; exit 0;; -k) ARG_CRYPT_KEY="$2"; shift; shift;; -l) ARG_LIST_FS=1; shift;; -n) ARG_DRY_RUN=1; shift;; -p) ARG_POPULATE_FS="$2"; shift; shift;; -t) ARG_TMP_DIR="$2"; shift; shift;; -v) ARG_VERBOSE=$(($ARG_VERBOSE + 1)); shift;; --) shift; break;; esac done if [ $# -lt 1 ]; then msg "aborting, disk image missing." exit 1 fi ARG_DISK_IMAGE="$1" if [ ! -f "$ARG_DISK_IMAGE" ]; then msg "aborting, could not open '$ARG_DISK_IMAGE'." exit 1 fi if [ $ARG_LIST_FS -eq 1 ] && [ $ARG_FORMAT_DEV -eq 1 ]; then msg "aborting, -f and -l are mutually exclusive." exit 1 fi if [ "$ARG_CRYPT_KEY" != "" ] && [ "$ARG_DISK_DEV" = "" ]; then ARG_DISK_DEV="/dev/cgd0a" fi [ "$ARG_DISK_DEV" != "" ] && RUMP_FORMAT_DISK_DEV="$ARG_DISK_DEV" [ $ARG_DRY_RUN -eq 1 ] && DRY_RUN=echo if [ $ARG_FORMAT_DEV -eq 1 ] && [ "$ARG_FORMAT_FS" = "" ]; then msg "aborting, filesystem type not specified." exit 1 fi } main() { local disk_dev= parse_arguments "$@" create_temp_dir "$ARG_TMP_DIR" export RUMP_SERVER="unix://$RUMP_TMP/server_socket" # # First we prepare the actions... # if [ "$ARG_FORMAT_FS" != "" ]; then RUMP_LIBS="$RUMP_LIBS -lrumpfs_$ARG_FORMAT_FS" # XXX [ "$ARG_FORMAT_FS" = "ext2fs" ] && RUMP_LIBS="$RUMP_LIBS -lrumpfs_ffs" fi if [ $ARG_FORMAT_DEV -eq 1 ]; then # only add the disk image as raw device if do not # already have another device [ "$ARG_DISK_DEV" = "" ] && disk_dev="$disk_dev -d key=$RUMP_DISK_DEV,hostpath=$ARG_DISK_IMAGE,size=host,type=chr" else [ "$ARG_DISK_DEV" = "" ] && disk_dev="$disk_dev -d key=$RUMP_DISK_DEV,hostpath=$ARG_DISK_IMAGE,size=host,type=blk" fi if [ $ARG_CRYPT_DEV -eq 1 ]; then RUMP_LIBS="$RUMP_LIBS -lrumpkern_crypto -lrumpdev_cgd -lrumpdev_rnd" disk_dev="-d key=$RUMP_DISK_DEV,hostpath=$ARG_DISK_IMAGE,size=host,type=blk" cgd_config="$RUMP_TMP/cgd0.conf" create_cgd_config "$cgd_config" "$ARG_CRYPT_KEY" disk_dev="$disk_dev -d key=/cgd0.conf,hostpath=$cgd_config,size=host,type=reg" fi if [ "$ARG_POPULATE_FS" != "" ]; then disk_dev="$disk_dev -d key=$RUMP_HOST_DIR,hostpath=$ARG_POPULATE_FS,size=host,type=dirs" fi # # ... and start the rump server... # rump_server "$RUMP_LIBS" "$disk_dev" # # ... then we execute the actions. # if [ $ARG_CRYPT_DEV -eq 1 ]; then do_crypt_dev "$ARG_CRYPT_KEY" if [ "$ARG_CRYPT_KEY" = "" ]; then $TOOL_DIR/rump_cgdconf -f "$cgd_config" fi fi if [ $ARG_FORMAT_DEV -eq 1 ]; then do_format_fs "$ARG_FORMAT_FS" "$RUMP_FORMAT_DISK_DEV" fi if [ "$ARG_POPULATE_FS" != "" ]; then do_mount_fs "$ARG_FORMAT_FS" "$RUMP_FORMAT_DISK_DEV" "/mnt" do_populate_fs "$ARG_POPULATE_FS" "/mnt" do_umount_fs "/mnt" fi if [ $ARG_LIST_FS -eq 1 ]; then do_mount_fs "$ARG_FORMAT_FS" "$RUMP_FORMAT_DISK_DEV" "/mnt" do_list_fs "/mnt" do_umount_fs "/mnt" fi exit 0 } PROG_NAME=$(basename $0) ARG_CRYPT_DEV=0 ARG_FORMAT_DEV=0 ARG_DRY_RUN=0 ARG_FORMAT_FS="" ARG_LIST_FS=0 ARG_TMP_DIR="" ARG_VERBOSE=0 DRY_RUN="" TOOL_DIR=$(dirname $(readlink -f $0)) GENODE_DIR=$(readlink -f $TOOL_DIR/..) RUMP_TMP="" RUMP_DIR="/usr/local/genode-rump" RUMP_PATH="$RUMP_DIR/bin" RUMP_LIBS="-lrumpdev -lrumpdev_disk -lrumpvfs" RUMP_SERVER="" RUMP_DISK_DEV=/disk_image RUMP_FORMAT_DISK_DEV="$RUMP_DISK_DEV" RUMP_HOST_DIR=/host trap "trap_abort" INT TERM trap "trap_exit" EXIT main "$@" exit 0 # End of file