Mount Disk Image On Loop Device

From Wiki
Jump to navigationJump to search

Overview

Shell script to mount an image of a disk (created by something like 'dd if=/dev/sda of=sda.img') to a local directory.

If the image is named 'disk.img', and the image has two partitions, then

./mu.sh mount disk.img

will create the following:

./disk
./disk/p1
./disk/p2

Where ./disk/p1 will be partition 1 from the image, ./disk/p2 will be partition 2, etc

Unmounting the image will remove the directory structure.

Caveat

I use this to mount Raspian images that get written to an SD card. I don't know exactly what will happen with extended partitions, swap partitions, etc.

Code

#!/bin/sh

mount_image () {
  MOUNTPOINT=${IMAGE##*/}
  MOUNTPOINT=${MOUNTPOINT%.*}
  MOUNTPOINT="${MOUNTPOINT}/p"

  COUNT=1
  LINES=`fdisk -lu ${IMAGE} | grep "^${IMAGE}"`

  echo "$LINES" | while read -r a; do
    OFFSET=`echo $a | cut --delimiter=' ' -f 2`
    NEXTFREELOOP=`losetup -f`
    MOUNTPOINTFULL="${MOUNTPOINT}${COUNT}"
    mkdir -p ${MOUNTPOINTFULL}
    CMD="losetup ${NEXTFREELOOP} ${IMAGE} -o $((OFFSET * 512))"
    if ! `${CMD}`; then
      echo "\"${CMD}\" failed. Stopping."
      exit 1
    fi
    CMD="mount ${NEXTFREELOOP} ${MOUNTPOINTFULL}"
    if ! `${CMD}`; then
      echo "\"${CMD}\" failed. Stopping."
      exit 1
    fi
    COUNT=$((COUNT + 1))
  done
}

umount_image () {
  MOUNTPOINT=${IMAGE##*/}
  MOUNTPOINT=${MOUNTPOINT%.*}
  MOUNTLIST="${MOUNTPOINT}/p*"

  for i in ${MOUNTLIST}; do
    CMD="umount -d $i"
    if ! `${CMD}`; then
      echo "\"${CMD}\" failed. Stopping."
      exit 1
    fi
  done

  rm -r ${MOUNTPOINT}
}

usage () {
  echo "Usage $0 {mount|umount} {image_name}"
  exit 1;
}

if [ "$#" -ne 2 ]; then
  usage
fi;

if ! [ $(id -u) = 0 ]; then
  echo "Script requires root privileges"
  exit 1
fi

if [ ! -f "$2" ]; then
  echo "File \"$2\" does not exist. Stopping."
  exit 1
fi

case $1 in
  mount)
    IMAGE="$2"
    mount_image
  ;;

  umount)
    IMAGE="$2"
    umount_image
  ;;

  *)
    usage
  ;;
esac

exit 0