Mounting IMG files under Linux [Updated]

Posted by

I have found a different approach to do this and I want to share it here.

From the original article Mounting IMG files under Linux: “Next to working on my MacBook Pro, I work most of the time on my new PC with Ubuntu 18.04 LTS. Still working with Raspberry Pi’s gives me the need to work with images to manipulate to my needs before I write them to the SD cards. This article assumes working on the Raspbian image that contains two partitions.

While the above paragraph is true, I do need to do it from time to time. In this case I have found issues with mounting the second partition from the image. The error I receive is: “overlapping loop device exists” although I set explicit sizelimit specifications in addition to the commands.

It has a different approach where the set of commands are available as a function that is called out of the .bashrc file. This is what has been added:

mntimg() (
   img="$1"
   dev="$(sudo losetup --show -f -P "$img")"
   echo "$dev"
   for part in "$dev"?; do
     if [ "$part" = "${dev}p" ]; then
       part="${dev}"
     fi
     dst="/media/$(basename "$part")"
     echo "$dst"
     sudo mkdir -p "$dst"
     sudo mount -t auto -o loop "$part" "$dst"
   done
 )

 umntimg() (
   dev="/dev/loop$1"
   for part in "$dev"; do
     if [ "$part" = "${dev}p" ]; then
       part="${dev}"
     fi
     dst="/media/$(basename "$part")"
     sudo umount "$dst"
   done
   sudo losetup -d "$dev"
 )

Different from aliases this method enables processing of more complex commands / functions to be executed.
What this means is that there are two commands created: mntimg and umntimg.

Now let’s break it down in to smaller pieces:

mntimg() (
   img="$1"
   dev="$(sudo losetup --show -f -P "$img")"
   echo "$dev"
   for part in "$dev"?; do
     if [ "$part" = "${dev}p" ]; then
       part="${dev}"
     fi
     dst="/media/$(basename "$part")"
     echo "$dst"
     sudo mkdir -p "$dst"
     sudo mount -t auto -o loop "$part" "$dst"
   done
 )

What happens here is:

  • mntimg is the function that is called. As it is part of the shell in the terminal you are working in, in the .bashrc file this function is not called but you call it by typing the command mntimg with as input /path/to/image/file. The command looks like:
    mntimg /path/to/image/file
    • img="$1" captures for the function the /path/to/image/file in a variable
    • dev="$(sudo losetup --show -f -P "$img")" executes the command losetup to enable the image as a loop back device and show the partitions in the image file and stores it in the variable dev.
    • echo "$dev" shows the loop back device like /dev/loop39. Note: remember the numeric part for later unmounting the image.
      • The next part with the for and if processes all partitions available in the img file.
      • dst="/media/$(basename "$part")" generates and stores the full path of the directory to be created to mount the partition to. Note: under Ubuntu /media is used to mount devices to that will show on the desktop if used.
      • echo "$dst" shows the full path for future reference if needed.
      • sudo mkdir -p "$dst" creates the directory where -p specifies to create the full path if parent folders do not exist.
      • sudo mount -t auto -o loop "$part" "$dst" mounts the partition in the image.
      • Where -t auto specifies to detect the partition type, -o loop specifies it is a loop device, "$part" is the loop device to mount and "$dst" is the directory to mount it to.
umntimg() (
   dev="/dev/loop$1"
   for part in "$dev"?; do
     if [ "$part" = "${dev}p" ]; then
       part="${dev}"
     fi
     dst="/media/$(basename "$part")"
     sudo umount "$dst"
   done
   sudo losetup -d "$dev"
 )

What happens here is:

  • umntimg is the function to unmount the partitions from the img file. Where the input is the numeric value from the loop device the img file is enabled on. In the previous example I used /dev/loop39. The command would be: umntimg 39
    • dev="/dev/loop$1" stores the input value (e.g. 39) together with the prefix of /dev/loop in the variable dev.
    • For each device with /dev/loop39? execute the following where ? represents any postfixes found.
      • dst="/media/$(basename "$part")" generates the full mount path and
      • sudo umount "$dst" actually unmounts the partition.
    • Once done and the loop is exited with done
    • sudo losetup -d "$dev" releases the loop device from the system.

I do like this approach as it makes my life easier that I do not have to remember all the steps.

This concludes this article.

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *