1

I hope I've posted this in the proper place, if I haven't then please advise me on where to move the post.

I've tried deciphering the kpartx output myself but now I'm sort of stuck and in need of guidance. I lack knowledge in many areas and I'm trying to improve, hence the deciphering. I'll post my problem and my findings so far and I'm hoping that someone out here could spare some of their time in guiding me in my troubleshooting/deciphering.

The problem

[root@hostname ~]# kpartx -l /dev/mapper/mpathcg 
mpathcg1 : 0 673171632 /dev/mapper/mpathcg 63

This number right here is my issue: 673171632. As far as I know, and also according to this answer https://serverfault.com/a/469734. This number should represent the number of blocks of this particular device.

[root@hostname ~]# fdisk -l /dev/mapper/mpathcg

Disk /dev/mapper/mpathcg: 344.7 GB, 344671125504 bytes
255 heads, 63 sectors/track, 41903 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 32768 bytes / 32768 bytes
Disk identifier: 0xa5c9e23d

          Device Boot      Start         End      Blocks   Id  System
/dev/mapper/mpathcgp1               1       41903   336585816   8e  Linux LVM
Partition 1 does not start on physical sector boundary.

But looking at the fdisk output, which I trust by experience, the number of blocks for this device is 336585816. To me, we have an inconsistency here. Since I trust fdisk by experience I was curious about how kpartx finds the number of blocks and then maybe look at fdisk and see how they differ from each other. So here is where the "deciphering" begun.

The actual question

I'm actually here for guidance, but in attempt to follow this forums guidelines and to help anyone else wondering the same thing:

How does kpartx determine it's output, in particular the number of blocks?

My findings so far

My number one finding: I'm terrible at reading C code...

kpartx/kpartx.c:

            printf("%s%s%d : 0 %" PRIu64 " %s %" PRIu64"\n",
                   mapname, delim, j+1,
                   slices[j].size, device,
                   slices[j].start);
        }

To me it seems that this struct called slice(s) has an element (or whatever the term is), named size. That is the size of a partition in blocks. Which is what get's outputed to stdout. However, I don't understand how it get populated with actual numbers.

kpartx/kpartx.h

struct slice {
    uint64_t start;
    uint64_t size;
    int container;
    int major;
    int minor;
};

This is what the struct looks like. Which seems to correpond to what kpartx outputs.

kpartx/kpart.c:

typedef int (ptreader)(int fd, struct slice all, struct slice *sp, int ns);
...
...
...
extern ptreader read_dos_pt;

These also seem intersting, I basing this on the name read_dos_pt, since the partition in questions is a dos partition and that ptreader seem to use the slice struct. Maybe to populate it?

kpartx/dos.c:

read_dos_pt(int fd, struct slice all, struct slice *sp, int ns) {
    struct partition p;
    unsigned long offset = all.start;
    int i, n=4;
    unsigned char *bp;
    uint64_t  sector_size_mul = get_sector_size(fd)/512;

    bp = (unsigned char *)getblock(fd, offset);

Here I notice the getblock function, which to me seems obvious for what I'm looking for. But looking at the getblock function in kpartx/kpartx.c I get lost and confused.

Any help I can get will be appreciated. Thank you for your time.

  • you mpatch disk is Lun export from SAN?, if your answer is yes, why you made partition on that? for alighment? do you know the latest lvm version do that for you? – c4f4t0r Sep 21 '17 at 10:26
  • 1
    This is in fact a SAN attached LUN. The partition is made on the device by habit there is no real thought of function behind it. – Mårten Olsson Sep 21 '17 at 16:17

1 Answers1

1

Not sure how relevant this is for serverfault, but I'll take it apart anyway.

Skip past getblock in read_dos_pt. Interesting part is on line 97. sp[i].size = sector_size_mul * le32_to_cpu(p.nr_sects); sector_size_mul is the number of 512 byte sectors in one native sector for this disk (eg, 4k disks would have a sector_size_mul of 8). Most likely, this will be 1, especially if it's a file you're probing.

p.nr_sects is being populated directly from the on-disk dos partition table using memcpy. The osdev wiki has a nice tabular dos partition format description, so you can see the nr_sects structure field is a uint32_t starting at byte 12 of the partition entry (cf. dos.h offset of partition.nr_sects).

Thus what kpartx is putting in that field is "the number of 512 byte sectors in the partition, regardless of native sector size."

Going back to your fdisk output, it's pretty clearly in 1k blocks.

Divide your byte size by 1024 and you're going to get the 336585816 number you're seeing in fdisk, but divide by 512 and you'll get what kpartx shows you.

Andrew Domaszek
  • 5,103
  • 1
  • 14
  • 26
  • Thank you, Andrew! I'm baffled by the quickness of your response, I did not expect it. Your explanation and the link you provided were both invaluable for my understanding, I appreciate it a lot. I don't understand all the details so I will play around with this a bit and see what more intriguing things I can find :) – Mårten Olsson Sep 21 '17 at 16:15