破译kpartx输出

我希望我已经在适当的地方张贴了这个,如果我没有,那么请告诉我移动post的位置。

我已经尝试破译kpartx输出自己,但现在我有点卡住,需要指导。 我在许多领域缺乏知识,我正在努力改进,从而破译。 我会把我的问题和我的发现发布到目前为止,我希望有人在这里可以腾出一些时间来指导我解决问题/解密。

问题

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

这个数字在这里是我的问题:673171632。据我所知,也根据这个答案https://serverfault.com/a/469734 。 这个数字应该代表这个特定设备的数。

 [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. 

但是看看我经验的fdisk输出,这个设备的块数是336585816.对我来说,我们在这里有一个不一致的地方。 由于我相信fdisk的经验,我很好奇kpartx如何find块的数量,然后看看fdisk,看看它们是如何不同的。 所以这就是“破译”开始的地方。

实际的问题

我实际上是在这里寻求指导,但是试图遵循这个论坛的指导方针,并帮助其他人想知道同样的事情:

如何kpartx确定它的输出,特别是块的数量?

我的发现迄今为止

我的头号发现:阅读C代码我很糟糕

kpartx / kpartx.c:

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

对我来说,这个称为slice(s)的结构似乎有一个元素(或任何术语),命名大小。 这是分块的大小。 这是什么得到输出到标准输出。 但是,我不明白如何填充实际的数字。

kpartx / kpartx.h

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

这就是结构的样子。 这似乎对应于kpartx输出。

kpartx / kpart.c:

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

这些也似乎intersting,我基于这个名字read_dos_pt,因为问题中的分区是一个DOS分区,并且ptreader似乎使用切片结构。 也许填充它?

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); 

在这里,我注意到了getblock函数,对我来说这似乎是显而易见的。 但是看看kpartx / kpartx.c中的getblock函数,我迷失了方向,感到困惑。

任何帮助,我可以得到赞赏。 感谢您的时间。

不知道这是如何相关的serverfault,但我会把它分开。

跳过read_dos_pt中的getblock。 有趣的部分是在行97. sp[i].size = sector_size_mul * le32_to_cpu(p.nr_sects); sector_size_mul是这个磁盘的一个本地扇区中512字节扇区的数量(例如,4k个磁盘的sector_size_mul是8)。 最有可能的是,这将是1,特别是如果它是一个你正在探测的文件。

正在使用memcpy从磁盘dos分区表直接填充p.nr_sects。 osdev wiki有一个很好的表格dos分区格式描述 ,所以你可以看到nr_sects结构字段是从分区条目的字节12开始的uint32_t(参见partition.nr_sects的dos.h偏移量)。

因此,kpartx在该领域的投入是“分区中的512字节扇区的数量,而不pipe本地扇区的大小”。

回到你的fdisk输出,它很明显在1k块。

将字节大小除以1024,你将得到你在fdisk中看到的336585816号码,但是除以512,你将得到kpartx显示的信息。