Slide 1

Slide 1 text

分散ストレージはすごいぞ Kernel/VM探検隊@北陸 Part 6 Dec, 2nd, 2023 Satoru Takeuchi X: satoru_takeuchi

Slide 2

Slide 2 text

あらすじ ● 2023年12月2日、人類はdevice mapperを使えばLinux上でディスク障害をエミュ レーションできることを知った ○ https://speakerdeck.com/sat/ozhang-hai-noemiyuresiyon

Slide 3

Slide 3 text

実験してみよう! ● オープンソースの分散ストレージCephのクラスタを対象とする ○ データをレプリケーションできる ○ レプリカが2個以上ある状態で1つのレプリカが壊れても、正しいデータから修復できる

Slide 4

Slide 4 text

実験してみよう! ● オープンソースの分散ストレージCephのクラスタを対象とする ○ データをレプリケーションできる ○ レプリカが2個以上ある状態で1つのレプリカが壊れても、正しいデータから修復できる ● 本当だろうか…試してみるまで俺は信用せんぞ

Slide 5

Slide 5 text

Cephのアーキテクチャ node node node disk OSD disk OSD disk OSD RADOS(独自インタフェースのオブジェクトストレージ ) ファイルシステム ブロックデバイス S3互換 オブジェクトストレージ

Slide 6

Slide 6 text

実験に使ったCephクラスタ node disk RADOS ファイル ファイル loop loop dm-dust dm-dust OSD OSD

Slide 7

Slide 7 text

問題: そもそもdm-dustデバイス上にOSDが作られねえ! node disk ファイル ファイル loop loop dm-dust dm-dust OSD OSD

Slide 8

Slide 8 text

問題: そもそもdm-dustデバイス上にOSDが作られねえ! ● Cephはlsblkコマンドによってデバイスのタイプを判断して、特定のタイプ上にのみ OSDを作る ○ disk, part, lvm, crypt, loop… node disk ファイル ファイル loop loop dm-dust dm-dust OSD OSD $ sudo lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7:0 0 6G 0 loop └─dust0 253:0 0 6G 0 dm loop1 7:1 0 6G 0 loop └─dust1 253:1 0 6G 0 dm

Slide 9

Slide 9 text

ソリューション: インチキしよう! ● lsblkのソースを読んでtypeフィールドの決め方を知る

Slide 10

Slide 10 text

ソリューション: インチキしよう! ● lsblkのソースを読んでtypeフィールドの決め方を知る ● dmデバイスなら、デバイスに設定されたUUIDが”foo-bar”なら”foo”を小文字にした ものがtypeとみなされる ○ もともとはcryptデバイスのUUIDがCRYPT-foobarのようになっているものを想定

Slide 11

Slide 11 text

ソリューション: インチキしよう! ● lsblkのソースを読んでtypeフィールドの決め方を知る ● dmデバイスなら、デバイスに設定されたUUIDが”foo-bar”なら”foo”を小文字にした ものがtypeとみなされる ○ もともとはcryptデバイスのUUIDがCRYPT-foobarのようになっているものを想定 ● sudo dmsetup create -u loop-foo test-dust test-dust.table

Slide 12

Slide 12 text

ソリューション: インチキしよう! ● lsblkのソースを読んでtypeフィールドの決め方を知る ● dmデバイスなら、デバイスに設定されたUUIDが”foo-bar”なら”foo”を小文字にした ものがtypeとみなされる ○ もともとはcryptデバイスのUUIDがCRYPT-foobarのようになっているものを想定 ○ sudo dmsetup create -u loop-foo test-dust test-dust.table ○ $ sudo dmsetup create -u loop-foo test-dust test-dust.table $ sudo lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7:0 0 6G 0 loop └─dust0 253:0 0 6G 0 loop loop1 7:1 0 6G 0 loop └─dust1 253:1 0 6G 0 loop

Slide 13

Slide 13 text

オブジェクトを作成 $ cat /tmp/test.data Hello Ceph world! $ rados -p replicapool put test-object test.data

Slide 14

Slide 14 text

GETする場合に読むOSDを得る $ ceph pg ls-by-pool replicapool PG OBJECTS … UP ACTING … 1.a 1 … [1,0]p1 [1,0]p1 … データはdust0上のOSD1から読む

Slide 15

Slide 15 text

オブジェクトの位置を知る ● stringsコマンドを使ってそれっぽいデータがあるセクタを疑似不良セクタとする ○ 本当はOSDの中にあるRocksDBを走査してセクタ番号を求めます $ sudo strings -t d /dev/mapper/dust1 | grep "Hello Ceph world!" 4616192 Hello Ceph world! ^C $ echo $((4616192/512)) 9016

Slide 16

Slide 16 text

疑似不良セクタを設定 $ sudo dmsetup message dust1 0 addbadblock 9016 0 $ sudo dmsetup message dust1 0 enable

Slide 17

Slide 17 text

オブジェクトをGET $ rados -p replicapool get test-object /tmp/out.data

Slide 18

Slide 18 text

中身は正しい! $ rados -p replicapool get test-object /tmp/out.data $ cat /tmp/out.data Hello Ceph world!

Slide 19

Slide 19 text

OSDのログにデータを修復した痕跡が! bdev(0x565452c64000 /var/lib/ceph/osd/ceph-1/block) _aio_thread got r=-5 ((5) Input/output error) 7ff464ab4700 -1 bdev(0x565452c64000 /var/lib/ceph/osd/ceph-1/block) _aio_thread translating the error to EIO for upper layer 7ff453291700 -1 log_channel(cluster) log [ERR] : 1.a missing primary copy of 1:5756f1fd:::test-object:head, will try copies on 0

Slide 20

Slide 20 text

おわり ● Cephは信用できるやつ ● 俺が悪かった