Skip to content

Instantly share code, notes, and snippets.

@RandallFlagg
Last active June 30, 2024 09:31
Show Gist options
  • Save RandallFlagg/2ac3f8245cbccb4095e56aaa6f92566d to your computer and use it in GitHub Desktop.
Save RandallFlagg/2ac3f8245cbccb4095e56aaa6f92566d to your computer and use it in GitHub Desktop.
Mount VHDX
#!/bin/bash
#TODO: Fix documentation
#TODO: Add an option for RW/RO
#TODO: Add tests to make sure there are no errors
# https://stackoverflow.com/questions/22009364/is-there-a-try-catch-command-in-bash
# https://stackoverflow.com/questions/15656492/writing-try-catch-finally-in-shell
# https://mywiki.wooledge.org/BashFAQ/105
#TODO: Select nbd device alone
#TODO: Translate this python code into bash: https://github.com/rhyven/MountNBD/blob/master/MountNBD.py
# Install
# install qemu utils
# sudo apt install qemu-utils
# install nbd client
# sudo apt install nbd-client
# Check if admin. If not, exit
if [ "$(id -u)" != "0" ]; then
echo "This script needs to be run as admin"
exit 126
fi
# Mount
VHDX_IMG="$1"
MOUNT_POINT="$2"
# sudo umount "$MOUNT_POINT" && sudo qemu-nbd -d /dev/nbd0 && sudo rmmod nbd
# sudo pkill qemu-nbd
# [ubuntu] How do you mount a VHD image
# https://ubuntuforums.org/showthread.php?t=2299701
#
target_drive=""
get_nbd_dev(){
# Initialize variables
target_drive="" #TODO: Change to local instead of the global variable
local nbd_drive=0
# Loop until a suitable NBD device is found
while [ -z "$target_drive" ]; do
# Check the size of the current NBD device
drive_size=$(blockdev --getsize64 "/dev/nbd$nbd_drive")
local ERROR=$?
if [ $? -eq 1 ]; then
echo "ERROR: blockdev: $ERROR"
exit "$ERORR"
fi
echo "Debug: drive size: $drive_size"
# If the drive size is 0, it's an empty NBD device
if [ "$drive_size" -eq 0 ]; then
# Set the target drive and log the information
target_drive="/dev/nbd$nbd_drive"
echo "nbd$nbd_drive is empty; using $target_drive as the target drive." >&2
else
# Try the next NBD device
echo "nbd$nbd_drive is already mapped to a file; trying the next one..." >&2
((nbd_drive++))
fi
done
# echo "DEBUG: get_nbd_dev result: $target_drive"
# return $target_drive
}
# Load the nbd kernel module.
rmmod nbd
rmmodError="$?"
if [ $rmmodError -ne 0 ]; then
if [ $rmmodError -ne 1 ]; then
echo "ERROR: rmmod $rmmodError"
exit $rmmodError
fi
fi
modprobe nbd max_part=16
get_nbd_dev
# echo "DEBUG: target_drive: $target_drive"
# mount block device
qemu-nbd -c $target_drive "$VHDX_IMG" #|| exit $?
# reload partition table
partprobe $target_drive
message="Done. Mounted $VHDX_IMG on $MOUNT_POINT with "
# mount partition
if [ "$3" == "--rw" ]; then
mount -t ntfs -o rw,nouser "$target_drive"p2 "$MOUNT_POINT"
message+="Read/Write mode"
else
mount -t ntfs -o ro,nouser "$target_drive"p2 "$MOUNT_POINT"
message+="Read only mode"
fi
echo "$message"
# Unmount
# MOUNT_POINT="$1"
#unmount & remove nbd module
# sudo umount "$MOUNT_POINT" && sudo qemu-nbd -d /dev/nbd0 && sudo rmmod nbd
# sudo pkill qemu-nbd
#Packages:
#libguestfs
#qemu
#supermin
#libselinux
#libguestfs-devel
#wget
# Hints:
#
# Run it as normal user, i.e.:
#
# guestmount ...
# Instead of:
#
# sudo guestmount ...
# Switches; citations from man page:
#
# --add
# Add a block device or virtual machine image.
#
# --inspector
# Using virt-inspector(1) code, inspect the disks looking for an operating system and mount filesystems as they would be mounted on the real virtual machine.
#
# --ro
# Add devices and mount everything read-only. Also disallow writes and make the disk appear read-only to FUSE.
#
# Test:
# libguestfs-test-tool
# FIXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# sudo
# export LIBGUESTFS_PATH=/usr/lib/guestfs
# guestfish --rw -a /media/DATA/data.vhdx
#
# Welcome to guestfish, the guest filesystem shell for
# editing virtual machine filesystems and disk images.
#
# Type: ‘help’ for help on commands
# ‘man’ to read the manual
# ‘quit’ to quit the shell
#
# Welcome to guestfish, the guest filesystem shell for
# editing virtual machine filesystems and disk images.
#
# Type: ‘help’ for help on commands
# ‘man’ to read the manual
# ‘quit’ to quit the shell
#
# ><fs> run
# ><fs> list-filesystems
# /dev/sda2: ntfs
# virt-filesystems -d MyGuest
# ><fs> exit
# FIXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
export LIBGUESTFS_PATH=/usr/lib/guestfs # Adjust path as needed
# export LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1
#if root
if [ $(id -u) = "0" ]; then
if [ ! -d "/usr/lib/guestfs" -or "$1" == "-f" ]; then
mkdir -p /usr/lib/guestfs
update-libguestfs-appliance
else
echo "The directory /usr/lib/guestfs exists. Exiting without doing anything. If you want to re-update appliance run as sudo with -f"
fi
echo "Run the script again without admin inorder to mount the VHDX"
else
# guestmount --add /media/DATA/data.vhdx --inspector --ro /media/VHDX
# guestmount --add /media/DATA/data.vhdx -o uid=1000 -o gid=1000 -o allow_other --rw /media/VHDX/ -m /dev/sda2
# guestmount --add /media/DATA/data.vhdx --rw /media/VHDX/ -m /dev/sda2
# guestmount --add "$1" --inspector --ro /mnt
guestmount -a "$1" -m /dev/sda -o uid=1000 -o gid=1000 --rw /media/VHDX/
fi
#!/bin/bash
# Check if admin. If not, exit
if [ "$(id -u)" != "0" ]; then
echo "This script needs to be run as admin"
exit 126
fi
MOUNT_POINT="$1"
NBD_DEVICE="$2"
echo "1: $1"
echo "2: $2"
#if $2 is not set
if [[ -z $2 ]]; then
echo "usage: UMountQemuNBD <MOUNT_POINT> <NBD_DEVICE>"
exit 1
fi
#unmount & remove nbd module
umount "$MOUNT_POINT" && sudo qemu-nbd -d "$NBD_DEVICE" && sudo rmmod nbd
pkill qemu-nbd
message="Done."
echo "$message"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment