Note to self 2022-09-15: if you are looking for a “firmware analyzer” or a tool that finds magic file headers at all locations inside of a file (and looks for embedded files). You need to look for your binwalk article.
INTRO
This method can be used to mount iso files and disk images (block device files) locally without burning them to drives. If they are iscsi luns you wont need to initiate to them, you can just mount them as if they were a disk image. The method covered here uses losetup to mount the disk image at the offsets where the partitions begin (so we need to use sgdisk and sfdisk to find out where the partitions start and end). At the end I throw in a bonus, using kpartx method, which will do everything automatically: it will mount all of the partitions in a disk image, without needing to parse the partition tables.
USING LOSETUP
If you have a file that is used as an iscsi_target, or perhaps its an iso of a disk, such a dd image of a drive sda, which had several partitions sda1, sda2, sda3. You can use this method to mount any partition, or to mount the iscsi_target. Note that an iscsi_target is no more than a simple disk, so an iscsi_target is like sda. In our example we have a file called lunfile, and lets assume this lunfile is like 10 gigs big (or however big your iscsi file is). This lunfile was either a dd image of drive that was partitioned using a local unix/linux system, or maybe it was initiated to with Windows initiator and has an NTFS filesystem on it – in the end it doesnt matter, all luns are just luns.
To mount ISCSI or a lun locally (which has partitions or no partitions), we just need to treat lunfile as a disk. So lunfile is like “sda”, its either MBR or GPT (depending on how you initialized the disk in windows), also it usually has partitions (usually just 1 if you set it up in windows). So the whole lunfile is “sda”, and at a certain offset begins “sda1”. A program called losetup can take an iso image of a disk (thats usually a burned cd) and associate that to a device called loop0 (or loop#, any number – or as many loop devices as your system allows). We can ask losetup to point lunfile to “loop0”, and then we can try to mount that “loop0” to /mnt, but that would FAIL. Why would it fail? because lunfile has partitions, it would be like trying to mount “sda” (instead of “sda1”). So instead we tell losetup to point at only a specific subsection of lunfile, and we call that subsection loop0, we can specify a start byte (using -o for offset, so like partition 1 starts at byte X), then usually it can autodetect how big that partition needs to be (if it cant detect how big it is, we can tell it that the partition is Y bytes big). Then loop0 is like sda1, instead of sda (or any other partition of sda), then we simply ask to mount loop0 to /mnt and it should work (granted you have the right mount tools – such as ntfs-3g for ntfs filesystems)
# losetup --help -a list all used loop devices -o, --offset <num> start at offset <num> into file --sizelimit <num> loop limited to only <num> bytes of the file
(STEP 0) cd to folder where lunfile is
cd /where/lun/file/is/
(STEP 1 – IF MBR) If MBR – Get the START and SIZE BYTES
# fdisk -lu lunfile You must set cylinders. You can do this from the extra functions menu. Disk disk.img: 0 MB, 0 bytes 255 heads, 63 sectors/track, 0 cylinders, total 0 sectors Units = sectors of 1 * 512 = 512 bytes Device Boot Start End Blocks Id System disk.imgp1 * 63 96389 48163+ 83 Linux disk.imgp2 96390 2056319 979965 82 Linux swap / Solaris disk.imgp3 2056320 78140159 38041920 5 Extended disk.imgp5 2056383 3052349 497983+ 83 Linux disk.imgp6 3052413 10859939 3903763+ 83 Linux disk.imgp7 10860003 68372639 28756318+ 83 Linux disk.imgp8 68372703 76180229 3903763+ 83 Linux disk.imgp9 76180293 78140159 979933+ 83 Linux
NOTE: output above is from another system. So ignore that your seeing disk.imgp1, it should be lunfilep1 (or something of that sort)
We need to figure out the START byte for the -o argument, and optionally figure out the SIZE of the partition for the –sizelimit argument.
Imagine we wanted to mount partition 7, p7, which is the biggest (has the most blocks). Notice its start sector 10860003. So we need to convert that bytes. We notice in that listing that 1 sector is 512 bytes. So the start location is 10860003*512 which is some big number (we dont need to calculate it, we will have linux/bash calculate for us).
Like I said in the intro, the SIZE of the partition doesnt really matter as much as the start point because it can guess the Size. But the Size would be something like (END-START)+1 to get the number of sectors. Dont forget to add 1 (unless it already adds one for us). Then multiply by 512 (bytes per sector) to get the number of bytes. 68372639-10860003+1. 57512637 sectors. Or 57512637*512 bytes. Note if we didnt add 1 it would be 57512636*512 bytes.
Why do we add 1? Well sometimes you have to try with adding it, and sometime without adding it. It depending on how they did the calcuation. Here is why – and simple math to throw off all the math you ever learned. How many fingers are you holding up when you hold up your 2nd thru 10th finger. The quick and wrong answer is 10-2 which is 8. The right answer is 10-2+1, which is 9. Try it: 2,3,4,5,6,7,8,9,10 (there are 9 digits there).
So here are the 2 numbers we need:
START BYTE: 10860003*512
SIZE (in BYTES): 57512637*512 or 57512636*512
(STEP 1 – IF GPT) If GPT – Get the START and SIZE BYTES
# sgdisk -p lunfile Disk lunfile: 23068672 sectors, 11.0 GiB Logical sector size: 512 bytes Disk identifier (GUID): 583A4103-15CA-488F-A159-FD887273A850 Partition table holds up to 128 entries First usable sector is 34, last usable sector is 23068638 Partitions will be aligned on 2-sector boundaries Total free space is 4029 sectors (2.0 MiB) Number Start (sector) End (sector) Size Code Name 1 34 65569 32.0 MiB 0C01 Microsoft reserved part 2 67584 23066623 11.0 GiB 0700 Basic data partition
So just like the MBR case, we need the START byte of the partition, and the size of the partition.
Notice the start sector of the biggest partition (where the data is) is 67584. Now we also see that a Logical Sector size is 512 bytes. So 67584*512 will give us the start byte. (Again we dont need to do the math as linux will do that)
Size of the partition is 23066623-67584+1 sectors, or without plus one 23066623-67584. Which is 22999040 or 22999039 sectors. Or 22999040*512 bytes or 22999039*512 bytes.
START BYTE: 67584*512
SIZE (in BYTES): 22999040*512 bytes 22999039*512 bytes
(STEP 2) Point the Partition to a Loop device
Now look for an available loop device. “losetup -a” will tell you what loop devices you have used. If you dont have one used then use loop0 or loop#, where # is any number.
SIDENOTE: Note a system can usually use like 10 loop devices max, but you can ask for more like this:
http://www.tldp.org/HOWTO/CDServer-HOWTO/addloops.html
http://www.cyberciti.biz/tips/set-maximum-number-of-loop-devices.html
http://unix.stackexchange.com/questions/55356/how-do-i-setup-more-then-10-loopback-device
We dont have to worry about that since we are only going to be using 1 loop device / 1 partition.
Then run 1 of the 6 losetup commands below, depending on if your MBR or GPT and if you tried the previous losetup command before that and it didnt work. First try the simple one.
SIDENOTE: the simplest losetup command would be to point the whole lunfile to loop0, but Ive tested that and it doesnt work – it doesnt work especially for ntfs-3g mounts. (it might work for ext and xfs, as those are mounts that look for the MAGIC NUMBER of their filesystem): losetup /dev/loop0 lunfile
*** FROM MBR CASE: ***
Recall the numbers were this:
START BYTE: 10860003*512
SIZE (in BYTES): 57512637*512 or 57512636*512
So the losetup command will be this:
losetup /dev/loop0 lunfile -o $((10860003*512))
If that doesnt work for step 3, we can try specifying the sizelimit (the size of the partition)
losetup /dev/loop0 lunfile -o $((10860003*512)) --sizelimit $((57512637*512))
Or this one (where we didnt add the +1):
losetup /dev/loop0 lunfile -o $((10860003*512)) --sizelimit $((57512636*512))
Most likely, the very first one will work. Either way one of those will work
*** FROM GPT CASE: ***
Recall the numbers were this:
START BYTE: 67584*512
SIZE (in BYTES): 22999040*512 bytes 22999039*512 bytes
So the losetup command will be this:
losetup /dev/loop0 lunfile -o $((67584*512))
If that doesnt work for step 4, we can try specifying the sizelimit (the size of the partition)
losetup /dev/loop0 lunfile -o $((67584*512)) --sizelimit $((22999040*512))
Or this one (where we didnt add the +1):
losetup /dev/loop0 lunfile -o $((67584*512)) --sizelimit $((22999039*512))
Most likely, the very first one will work. Either way one of those will work
(STEP 3) Mount the Loop device
mount /dev/loop0 /mnt
Or if its NTFS
apt-get update apt-get install ntfs-3g ntfs-3g /dev/loop0 /mnt
SIDENOTE: if your ISCSI is in use right now by its initiator, try mounting the filesystem as readonly with -o ro.
mount -o ro /dev/loop0 /mnt
or
ntfs-3g -o ro /dev/loop0 /mnt
To undo everything:
You will need to do this if you want to try other losetup commands
To detach everything. First unmount the filesystem:
umount /mnt
Then detach the loop device.
losetup -d /dev/loop0
Check its detached with losetup -a:
losetup -a
USING KPARTX
KpartX uses the loop block devices to mount the disk images from different offsets. Each loop can be pointed to 1 file @ specific offset. KpartX points loop at whole file. Then dev mapper breaks appart each loop file into the partitions and then you see the partitions in /dev/mapper folder.
NOTE: I show examples using various different disk images, I dont just stick to showing disk image.
First download kpartx
apt-get install kpartx
SIDENOTE: to mount ntfs, download ntfs-3g: apt-get install ntfs-3g & to mount vmfs download vmfs-tools: apt-get install vmfs-tools
Find the disk image and run this command to see how the partitions will be split up:
# kpartx -l /data/somediskimg0.img GPT:Primary header thinks Alt. header is not at the end of the disk. GPT:Alternate GPT header not at the end of the disk. GPT: Use GNU Parted to correct GPT errors. loop1p1 : 0 4294963200 /dev/loop1 2048
Find the disk image and run this command to mount somedisk.img:
# kpartx -v -a /data/somedisk.img
-v for verbose output, -a to attach the somedisk.img to the loop files and split up its partitions into /dev/mapper.
It will then make /dev/loop0 pointed at somedisk.img. Then its 3 partitions will be in
# ls -1 /dev/mapper control loop0p1 loop0p2 loop0p3
Ignore the control file.
Now you can use file -s /dev/loop0p1 to find out the filesystem type and continue to mount them.
# mount /dev/mapper/loop0p1 /mnt/p1 # ntfs-3g /dev/mapper/loop0p1 /mnt/p2 # vmfs-fuse /dev/mapper/loop0p1 /mnt/p3 ## ex: 1st partition was ext3, 2nd partition was ntfs, 3rd partition was vmfs
If you then point kpartx -a at another file it will create loop1 and loop1
To recap all of your loop points
# to list the loop devices and what they are attached to losetup -a # to see the partitions it found ls -lisah /dev/mapper
Example:
# losetup -a /dev/loop0: [0011]:258 (/data/disk3.img) /dev/loop1: [001e]:258 (/data/disk4.img) # ls -lisah /dev/mapper total 0 371 0 drwxr-xr-x 2 root root 100 Jul 8 18:55 . 1102 0 drwxr-xr-x 7 root root 2.3K Jul 8 18:55 .. 372 0 crw-rw---- 1 root root 10, 236 Jul 8 09:04 control 1613 0 brw-r--r-- 1 root root 253, 0 Jul 8 18:54 loop0p1 1616 0 brw-r--r-- 1 root root 253, 1 Jul 8 18:55 loop1p1 # summary: so we know disk3.img made loop0 with 1 partition (loop0p1). disk4.img made loop1 with 1 partition (loop1p1)
Now you can mount loop0p1 or loop1p1 using your mount commands: mount, ntfs-3g, vmfs-fuse
Now how do you undo all of this, and get the loop devices back to an unused state? Well we simply have to use kpartx to delete the loop devices.
## STEP1) I want to undo /dev/loop1. First find out the filename of the disk image you want to undo, using losetup -a # losetup -a /dev/loop0: [0011]:258 (/data/disk3.img) /dev/loop1: [001e]:258 (/data/disk4.img) ## STEP2) We see loop1 is /data/disk4.img. So now we delete the loop device with kpartx. kpartx -d /data/disk4.img NOTE: you first need to unmount all of the loop devices partitions. NOTE: you cant use losetup -d to remove the loop devices, it will say its in use (as its in use by dev mapper to make the partitions in /dev/mapper). you have to remove the loop devices with kpartx
The end.
One thought on “Mount/Initiate to Iscsi Luns Locally – Mount Luns – Mount Partitioned ISOs”