web-dev-qa-db-ja.com

kpartx出力の解読

適切な場所に投稿したことを願っています。まだ投稿していない場合は、投稿の移動先を教えてください。

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がブロックの数を見つける方法に興味があり、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)と呼ばれるこの構造体には、sizeという名前の要素(または用語が何であれ)があるように見えます。これは、ブロック単位のパーティションのサイズです。これがstdoutに出力されるものです。ただし、実際の数値がどのように入力されるのかわかりません。

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;

問題のパーティションはdosパーティションであり、そのptreaderはスライス構造体を使用しているように見えるため、これらも興味深いようです。これは、read_dos_ptという名前に基づいています。多分それを投入する?

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関数を見ると、迷って混乱します。

私が得ることができるどんな助けでもありがたいです。お時間をいただきありがとうございます。

1
Mårten Olsson

これがserverfaultにどの程度関連しているかはわかりませんが、とにかく分解します。

Read_dos_ptのgetblockをスキップします。興味深い部分は97行目です。sp[i].size = sector_size_mul * le32_to_cpu(p.nr_sects);sector_size_mulは、このディスクの1つのネイティブセクター内の512バイトセクターの数です(たとえば、4kディスクにはsector_size_mul of 8)。ほとんどの場合、これは1になります。特に、プローブしているファイルの場合はそうです。

p.nr_sectsは、memcpyを使用してディスク上のdosパーティションテーブルから直接入力されています。 osdev wikiには素敵な表があります dosパーティション形式の説明 、nr_sects構造フィールドがパーティションエントリのバイト12から始まるuint32_tであることがわかります(partition.nr_sectsのdos.hオフセットを参照) 。

したがって、kpartxがそのフィールドに入力しているのは、「ネイティブセクターのサイズに関係なく、パーティション内の512バイトセクターの数」です。

Fdisk出力に戻ると、1kブロックでかなり明確になっています。

バイトサイズを1024で割ると、fdiskに表示されている336585816の数値が得られますが、512で割ると、kpartxに表示される数値が得られます。

1
Andrew Domaszek