]> git.pld-linux.org Git - packages/VirtualBox.git/blob - mount.vdi
- mount(1) helper to mount partitions from VirtualBox .vdi images.
[packages/VirtualBox.git] / mount.vdi
1 #!/bin/sh
2 #==============================================================================
3 # mount.vdi
4 #   Copyright (C) Elan Ruusamäe <glen@pld-linux.org>, 2008
5 #
6 #   This program is free software; you can redistribute it and/or
7 #   modify it under the terms of the GNU General Public License as
8 #   published by the Free Software Foundation; either version 2 of
9 #   the License, or (at your option) any later version.
10 #
11 #   This program is distributed in the hope that it will be useful,
12 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 #   General Public License for more details.
15 #
16 #   You should have received a copy of the GNU General Public
17 #   License along with this program; if not, write to:
18 #   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 #   Boston, MA  02110-1301  USA
20 #
21 #   -- For details, see the file named "LICENSE.GPLv2"
22 #==============================================================================
23
24 # Sanitize environment
25 export PATH=/bin:/sbin:/usr/bin:/usr/sbin
26
27 # Commands
28 LOSETUP=/sbin/losetup
29 MOUNT=/bin/mount
30
31 PROGRAM=${0##*/}
32 OPTIONS=
33 FSTYPE=
34
35 USAGE="VDI image mountpoint [-o options,...]
36
37 Options:
38       partition=<number>              Specify partition to mount
39       fstype=<fstype>                 Specify FS type instead of autodetecting
40 "
41
42 # This is braindead, two first args are dev and mountpoint if invoked from
43 # mount(1), but could be option if invoked from mount.vdi(1)
44 if [ -n "$1" ] && [[ "$1" != -* ]]; then
45         DEVICE=$1
46         shift
47 fi
48 if [ -n "$1" ] && [[ "$1" != -* ]]; then
49         MOUNTPOINT=$1
50         shift
51 fi
52
53 while :; do
54         case "$1" in
55         -h | "-?" )
56                 echo >&2 "Usage: $PROGRAM $USAGE"
57                 exit 0 ;;
58         -o )
59                 OPTIONS="$2";
60                 shift ;;
61         -?* )
62                 echo >&2 "$PROGRAM: unrecognized option: $1"
63                 exit 1 ;;
64         *)
65                 break ;;
66         esac
67         shift
68 done
69
70 if [ -z "$DEVICE" ]; then
71         echo >&2 "$PROGRAM: device to mount not specified"
72         exit 1
73 fi
74
75 if [ -z "$MOUNTPOINT" ]; then
76         echo >&2 "$PROGRAM: mount point not specified"
77         exit 1
78 fi
79
80 if [ ! -f "$DEVICE" ]; then
81         echo >&2 "$PROGRAM: $DEVICE is not a file"
82         exit 1
83 fi
84
85 if [ ! -d "$MOUNTPOINT" ]; then
86         echo >&2 "$PROGRAM: $MOUNTPOINT is not a directory"
87         exit 1
88 fi
89
90 # check magic
91 magic=$(head -n 1 "$DEVICE")
92 if [ "$magic" != "<<< innotek VirtualBox Disk Image >>>" ]; then
93         echo >&2 "$PROGRAM: $DEVICE: bad magic, not VDI image"
94         exit 1
95 fi
96
97 MOUNTOPTIONS=
98 PARTITION=
99 OFFSET=
100 OLDIFS=$IFS
101 IFS=", "
102 for opt in $OPTIONS; do
103     KEY=${opt%=*};
104     VAL=${opt#*=};
105         case "$KEY" in
106         part|partition)
107                 PARTITION="$VAL"
108                 ;;
109         fstype)
110                 FSTYPE="$VAL"
111                 ;;
112         *)
113                 if [ -z "$MOUNTOPTIONS" ]; then
114                         MOUNTOPTIONS="$opt"
115                 else
116                         MOUNTOPTIONS="$MOUNTOPTIONS,$opt"
117                 fi
118         ;;
119         esac
120 done
121 IFS="$OLDIFS"
122
123 if [ -z "$PARTITION" ]; then
124         echo >&2 "$PROGRAM: missing partition option"
125         exit 1
126 fi
127
128 # offset when disk starts
129 dskoff=8704
130
131 # find free loop device. XXX race possible
132 imgdev=$(losetup -f)
133 losetup $imgdev -o $dskoff "$DEVICE"
134 # http://vserver.13thfloor.at/Stuff/QEMU/hdloop.sh
135 sfd=$(/sbin/sfdisk -dump $imgdev 2>/dev/null | sed -n ' 
136         /:/ s/[a-zA-Z]*=\ *\([0-9a-f]*\)\(,\|$\)/\1/g;
137         T;  s/^.*:\ //; p' | tr ' ' '.')
138 losetup -d $imgdev
139
140 getoffset() {
141         pstart=$1
142         psize=$2
143
144         blksize=512
145         offset=$((pstart*blksize))
146         size=$((psize*blksize))
147         echo $((offset+dskoff))
148 }
149
150 p=1
151 for a in $sfd; do
152         if [ "$p" = "$PARTITION" ]; then
153                 OFFSET=$(getoffset $(echo "$a" | tr '.' ' '))
154         fi
155         x=$((p++))
156 done
157
158 if [ -z "$OFFSET" ]; then
159         echo >&2 "$PROGRAM: couldn't figure out offset, perhaps out of range?"
160         exit 1
161 fi
162
163 if [ -z "$MOUNTOPTIONS" ]; then
164         MOUNTOPTIONS="offset=$OFFSET"
165 else
166         MOUNTOPTIONS="$MOUNTOPTIONS,offset=$OFFSET"
167 fi
168
169 # $MOUNTPOINT might not exist as mount can try to read it from /etc/fstab
170 "$MOUNT" ${FSTYPE:+-t "$FSTYPE"} ${MOUNTOPTIONS:+-o "$MOUNTOPTIONS"} "$DEVICE" "$MOUNTPOINT"
171 if [ $? -ne 0 ]; then
172     echo >&2 "$PROGRAM: error mounting $DEVICE"
173 fi
This page took 0.046469 seconds and 4 git commands to generate.