1

I am trying to programmatically mount partition tables in linux with a partition table.

Heres what I did so far to see if I can mount a partition in backup with a damaged drive (deleted partition table) using losetup. I am assuming that I am able to find the beginning and end sectors here.

I created a new file containing 2 partitions using

sudo dd if=/dev/zero of=backup.img bs=1M count=100

sudo fdisk backup.img and partitioned backup.img into two partitions, after which sudo fdisk -lu backup.img shows as follows

Device   Boot  Start   End   Sectors   Size Id   Type
backup.img1       2048  104447  102400    50M 83   Linux
backup.img2     104448  204799  100352    49M 83   Linux

The partitions here are ext3 and ext4 partitions as I am just testing if I can mount partitions with a non-existant partion table using losetup

Then I tried this

sudo losetup -r -o 1048576 /dev/loop0 backup.img works, after which I can do sudo mount /dev/loop0 /mnt/test.

However, I am assuing that I have a raw image with no partition table, so I have to manually provide the partition table. Also I dont want to mess with the existing backup as it could damage the disk further.

sudo losetup -o 1048576 --sizelimit 52428288 /dev/loop0 backup.img works.

However, when I try to mount the loop device using

sudo mount /dev/loop0 /mnt/test, it fails saying

mount: /mnt/test: wrong fs type, bad option, bad superblock on /dev/loop0, missing codepage or helper program or other error

Why does losetup not recognize the partition when I provide the sizelimit?

Is there something I am missing here?

13
  • 1
    Why the -o 40000 in the otherwise very sensible losetup call? Also, does file sda2.img agree this is a file system containing image? Commented Aug 31, 2023 at 7:23
  • thats the offset for the start of the partition of apfs Commented Aug 31, 2023 at 20:51
  • the question is when I use losetup, does it just try to replicate a system similar to the /dev/sda2 when I mount the usb drive, or is it doing something different? 400000 is just approximate Commented Aug 31, 2023 at 20:55
  • "just approximate" will never do, why do you do that?. Loser up does nothing - it just takes a file (and optionally, an offset into that for) and tells the kernel "make a block device backed by this file". So, if that file contains an image of a partition with a file system on it, that can than be mounted. If not, then not. What does your sda2.img contain? Commented Aug 31, 2023 at 21:49
  • 1
    Bit confused, a raw image of a while disk would always contain the partition table Commented Sep 1, 2023 at 7:48

2 Answers 2

0

There's nothing wrong in theory with the commands you are using to setup the loop device. I use something similar in build scripts to generate images.

My guess is that you accidentally formatted your test image incorrectly, perhaps you made the ext file system larger than it should have been.

Loop devices are just block devices pointing to a section of a file and they know nothing about the partition table. Likewise partitions are nothing more than a section on the disk with a table entry describe where on disk they are.

The easiest way to get block devices for your partitions is to use the partition table which should be there on any disk.

You can actually ask Linux to add loop partitions for you if the image already has a partition table:

loop_device=$(losetup --show -f my image.img)
partx -a $loop_device

This will create a set of devices such as /dev/loop2 /dev/loop2p1 /dev/loop2p2. This avoids you messing around with calculating offsets.

0
0

You do not need sudo in your dd command, the following is OK:

dd if=/dev/zero of=backup.img bs=1M count=100

Again, to create/edit the partition table in there, you do not need sudo:

$ gdisk backup.img 
GPT fdisk (gdisk) version 1.0.8

Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries in memory.

Command (? for help): o
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): y

Command (? for help): n
Partition number (1-128, default 1): 
First sector (34-204766, default = 2048) or {+-}size{KMGTP}: 
Last sector (2048-204766, default = 204766) or {+-}size{KMGTP}: 102400
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): 8300
Changed type of partition to 'Linux filesystem'

Command (? for help): c
Using 1
Enter name: Test_1

Command (? for help): n
Partition number (2-128, default 2):  
First sector (34-204766, default = 104448) or {+-}size{KMGTP}: 
Last sector (104448-204766, default = 204766) or {+-}size{KMGTP}: 
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): c
Partition number (1-2): 2
Enter name: Test_2

Command (? for help): p
Disk backup.img: 204800 sectors, 100.0 MiB
Sector size (logical): 512 bytes
Disk identifier (GUID): 61A000F6-7F51-4615-B1B6-82D4C9E305B3
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 204766
Partitions will be aligned on 2048-sector boundaries
Total free space is 4061 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048          102400   49.0 MiB    8300  Test_1
   2          104448          204766   49.0 MiB    8300  Test_2

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to backup.img.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.

And the same goes for showing the partition table, no sudo:

$ fdisk -l backup.img 
Disk backup.img: 100 MiB, 104857600 bytes, 204800 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 61A000F6-7F51-4615-B1B6-82D4C9E305B3

Device       Start    End Sectors Size Type
backup.img1   2048 102400  100353  49M Linux filesystem
backup.img2 104448 204766  100319  49M Linux filesystem

Now you want some file system on those partitions, ok, let me create both ext4, type of file system I believe does not matter at this point.

$ sudo kpartx -a backup.img

$ losetup --list | grep backup.img
/dev/loop19         0      0         0  0 /home/vlastimil/partition-experiments/backup.img       0     512

$ sudo mkfs.ext4 -L Test_ext4_1 -m 0 -E lazy_itable_init=0,lazy_journal_init=0 /dev/mapper/loop19p1 
mke2fs 1.46.5 (30-Dec-2021)
Discarding device blocks: done                            
Creating filesystem with 12544 4k blocks and 12544 inodes

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done

# The same command for /dev/mapper/loop19p2

After that, I mean after creating an image of a disk, I mounted it always using sectors multiplied by, but as we used kpartx above, it simplified it to:

$ mkdir mntpoint
$ sudo mount /dev/mapper/loop19p1 mntpoint1/
$ sudo mount /dev/mapper/loop19p2 mntpoint2/

Now, you shall have both partitions mounted.

1
  • thanks for the detailed writeup. didnt try running without sudo, but my issue before was different. I think I solved it for now.. Commented Sep 4, 2023 at 20:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .