#!/bin/sh #============================================================================== # mount.vdi # Copyright (C) Elan Ruusamäe , 2008 # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public # License along with this program; if not, write to: # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, # Boston, MA 02110-1301 USA # # -- For details, see the file named "LICENSE.GPLv2" #============================================================================== # Sanitize environment export PATH=/bin:/sbin:/usr/bin:/usr/sbin # Commands LOSETUP=/sbin/losetup MOUNT=/bin/mount PROGRAM=${0##*/} MOUNTARGS= OPTIONS= FSTYPE= USAGE="VDI image mountpoint [-o options,...] Options: partition= Specify partition to mount fstype= Specify FS type instead of autodetecting " # This is braindead, two first args are dev and mountpoint if invoked from # mount(1), but could be option if invoked from mount.vdi(1) if [ -n "$1" ] && [[ "$1" != -* ]]; then DEVICE=$1 shift fi if [ -n "$1" ] && [[ "$1" != -* ]]; then MOUNTPOINT=$1 shift fi while :; do case "$1" in -h | "-?" ) echo >&2 "Usage: $PROGRAM $USAGE" exit 0 ;; -o) OPTIONS="$2"; shift ;; -n) MOUNTARGS="$MOUNTARGS $1" ;; -?* ) echo >&2 "$PROGRAM: unrecognized option: $1" exit 1 ;; *) break ;; esac shift done if [ -z "$DEVICE" ]; then echo >&2 "$PROGRAM: device to mount not specified" exit 1 fi if [ -z "$MOUNTPOINT" ]; then echo >&2 "$PROGRAM: mount point not specified" exit 1 fi if [ ! -f "$DEVICE" ]; then echo >&2 "$PROGRAM: $DEVICE is not a file" exit 1 fi if [ ! -d "$MOUNTPOINT" ]; then echo >&2 "$PROGRAM: $MOUNTPOINT is not a directory" exit 1 fi # check magic magic=$(head -n 1 "$DEVICE") if [ "$magic" != "<<< innotek VirtualBox Disk Image >>>" ]; then echo >&2 "$PROGRAM: $DEVICE: bad magic, not VDI image" exit 1 fi MOUNTOPTIONS= PARTITION= OFFSET= OLDIFS=$IFS IFS=", " for opt in $OPTIONS; do KEY=${opt%=*}; VAL=${opt#*=}; case "$KEY" in part|partition) PARTITION="$VAL" ;; fstype) FSTYPE="$VAL" ;; *) if [ -z "$MOUNTOPTIONS" ]; then MOUNTOPTIONS="$opt" else MOUNTOPTIONS="$MOUNTOPTIONS,$opt" fi ;; esac done IFS="$OLDIFS" if [ -z "$PARTITION" ]; then echo >&2 "$PROGRAM: missing partition option" exit 1 fi # offset when disk starts dskoff=8704 # find free loop device. XXX race possible imgdev=$(losetup -f) losetup $imgdev -o $dskoff "$DEVICE" # http://vserver.13thfloor.at/Stuff/QEMU/hdloop.sh sfd=$(/sbin/sfdisk -dump $imgdev 2>/dev/null | sed -n ' /:/ s/[a-zA-Z]*=\ *\([0-9a-f]*\)\(,\|$\)/\1/g; T; s/^.*:\ //; p' | tr ' ' '.') losetup -d $imgdev getoffset() { pstart=$1 psize=$2 blksize=512 offset=$((pstart*blksize)) size=$((psize*blksize)) echo $((offset+dskoff)) } p=1 for a in $sfd; do if [ "$p" = "$PARTITION" ]; then OFFSET=$(getoffset $(echo "$a" | tr '.' ' ')) fi x=$((p++)) done if [ -z "$OFFSET" ]; then echo >&2 "$PROGRAM: couldn't figure out offset, perhaps out of range?" exit 1 fi if [ -z "$MOUNTOPTIONS" ]; then MOUNTOPTIONS="offset=$OFFSET" else MOUNTOPTIONS="$MOUNTOPTIONS,offset=$OFFSET" fi # $MOUNTPOINT might not exist as mount can try to read it from /etc/fstab "$MOUNT" $MOUNTARGS ${FSTYPE:+-t "$FSTYPE"} ${MOUNTOPTIONS:+-o "$MOUNTOPTIONS"} "$DEVICE" "$MOUNTPOINT" if [ $? -ne 0 ]; then echo >&2 "$PROGRAM: error mounting $DEVICE" fi