Acu multi ani, cand voiai sa faci un target de ISCSI pe Linux, existau tgtd si tgtadm. Pen’ca tgtd rula in userspace, avea ceva penalitati de performanta, ca luai chestii de pe disk si le trimiteai peste retea. Niste oameni, adica Datera prin http://linux-iscsi.org/wiki/LIO au scris toata partea de target si initiator in kernel ca sa nu mai faci context-switching aiurea fara motiv.
Partea misto e ca pe langa ISCSI “normal” au implemenant si primitivele VAAI ale lui VMware si accelereaza diverse operatiuni pe care le face ESXi: gen zero-ing, copiere si scriere de date de pe acelasi LUN etc.
Intr-un proiect de acu aveam nevoie de shared storage pentru niste ESXi-uri si m-am apucat sa fac niste target-uri pe un CentOS7. Initial din toate discurile de aveam sa le export, am exportat unul singur mi-am facut treaba si restul sa le export cand aveam nevoie de ele.
Intr-o zi cu soare am ajuns si la exportat restul de discuri ca aveam nevoie de loc unde sa fac backup, sa mut niste masini pe niste discuri mai rapide etc.
Am adaugat si restul de discuri ca LUN-uri, le-am mapat in ESXi-uri si m-am luat cu alta treaba. A doua zi incepe lumea sa se agite ca bai nu mai merge “serverul”, unde “serverul” era un VM pe care lucrau oamenii. Pana a ajuns la mine asta, pana am terminat ce aveam de facut, a inceput sa mearga “serverul”. Am zis ca cine stie, o fi sughitat reteaua sau ceva (ca lumea era pe Wi-Fi si na… nu e obligatoriu sa mearga mereu ca te mai pui cu laptop-ul aiurea si poate nu ai cel mai bun semnal) si d’aia n-a mers, ca nici nu a stiu lumea sa-mi spuna exact ce inseamna “nu merge”.
A doua zi dupa incident, eram eu pe langa rack-uri si trageam de niste cabluri pe acolo, cand aud un bipait din ala de cand buteaza un server. M-am apucat sa ascult sa vad de unde e, da pana am gasit un monitor, pana l-am montat, pana am luat-o din server in server, totul era iar OK. Dupa aia am luat-o cu verificat de uptime-uri, pana dau de asta cu storage care avea uptime de cateva minute.
Evident, dictai WTF-ul pe fata mea, ca n-atinsesem nimic care sa-l afecteze. Noroc ca mai eram cu cineva acolo pe post de martor, ca zicea lumea ca-i sabotez. E, cat incercam io sa ma uit in loguri sa vad ce-ar fi putut sa aiba (bine, sperand sa gasesc loguri), vad cum incepe un kdump sa ruleze si buf, reboot iar.
Cat am apucat io sa vad ce scria pe ecran, baga ceva cu “BIOS corrupted by…”. Zic sa vezi acu distractie, ca daca e ceva de BIOS si nu exista update la producator, o sa se lase cu sugeri maxime, ca aia n-o sa fixeze peste noapte si o sa dureze pana se prind ce ma-sa are.
Cat ma gandeam eu la posibilitati si ce-ar putea sa aiba, s-a rebutat, a pornit fain frumos, a mai mers vreo 10-15 minute si iar kdump si biiip restart.
Eram asa un pic cu morcovul in cur ca 1) lumea chiar avea nevoie de storage pentru VM-uri 2) eu propusesem solutia. Mai mult 2) ma ardea maxim. Ca ma gandeam c-am pizdit-o grav. Desi era prima oara cand se intampla asta, am auzit de atatea ori scuza asta la diversi cu “pana acu nu mi s-a intamplat” ca ma gandeam ca sigur o sa ma creada din parti clientul daca zic si io asta. Ca eu sigur nu l-as fi crezut pe unul cand zice asta.
Si m-am apucat sa ma gandesc ca ma-sa s-a schimbat intre timp, ce-am facut, unde, de ce. Si nu imi venea nimic in cap sa fi facut acolo, care sa prezinte un risc. Pana cand dupa vreo ora asa, si vreo 2 reboot-uri, m-a palit ca poate e de la ISCSI ca adaugasem alea 2 LUN-uri in portal.
Le-am demonat de pe ESXi-uri, le-am sters din portal si am asteptat sa vad daca mai crapa.
Si n-a mai crapat.
Dupa ce mi-a trecut sperietura cu asta, am inceput sa ma gandesc ca “ba bine, nu mai crapa, da acu ce cacat fac cu restul de discuri, ca nu pot sa nu le mai prezint la ESXi-uri, ca am nevoie de ele”. Cat timp ma gandeam eu la asta, mi-am adus aminte de kdump. Si m-am apucat sa ma uit prin ele, ca se salvasera toate de cand a inceput sa moara kernelul.
Si mi-a trecut panica, ca absolut de fiecare data crapa in acelasi loc:
[ 5241.534120] BUG: unable to handle kernel NULL pointer dereference at 000000000000001c [ 5241.534194] IP: [<ffffffff816abb5c>] _raw_spin_lock+0xc/0x30 [ 5241.534245] PGD 0 [ 5241.534264] Oops: 0002 [#1] SMP [ 5241.536014] Call Trace: [ 5241.536048] [<ffffffffc05d1c90>] ? target_complete_ok_work+0x180/0x330 [target_core_mod] [ 5241.536109] [<ffffffff810a881a>] process_one_work+0x17a/0x440 [ 5241.536153] [<ffffffff810a94e6>] worker_thread+0x126/0x3c0 [ 5241.536196] [<ffffffff810a93c0>] ? manage_workers.isra.24+0x2a0/0x2a0 [ 5241.536244] [<ffffffff810b098f>] kthread+0xcf/0xe0 [ 5241.536281] [<ffffffff810b08c0>] ? insert_kthread_work+0x40/0x40 [ 5241.536327] [<ffffffff816b4f58>] ret_from_fork+0x58/0x90 [ 5241.536367] [<ffffffff810b08c0>] ? insert_kthread_work+0x40/0x40 [ 5241.536410] Code: 5d c3 0f 1f 44 00 00 85 d2 74 e4 0f 1f 40 00 eb ed 66 0f 1f 44 00 00 b8 01 00 00 00 5d c3 90 0f 1f 44 00 00 31 c0 ba 01 00 00 00 <f0> 0f b1 17 85 c0 75 01 c3 55 89 c6 48 89 e5 e8 a4 2a ff ff 5d [ 5241.536649] RIP [<ffffffff816abb5c>] _raw_spin_lock+0xc/0x30 [ 5241.536694] RSP <ffff88085de0fdf8> [ 5241.536720] CR2: 000000000000001c
Bine, mi-a trecut panica ca m-am gandit eu ca ba, sa vezi ca se confuzeaza in vreo chestie de concurrency ca mai multe host-uri vor chestii relativ similare de pe mai multe discuri in acelasi timp si poate se dezaloca ceva aiurea si d’aia ajunge ala in NULL pointer dereference. Sau poate cand aloca nu si incrementeaza numarul de alocari si prima dezalocare merge da restul nu mai au cum… Sau ceva de SerDes aiurea la scrieri/citiri.
Da’ fiind in _raw_spin_lock cand crapa… slabe sanse sa pot debuga ceva, ca asta e treaba de lucruri low level in kernel.
Long-story short: mai multe LUN-uri intr-un portal exportate la mai multe host-uri != love.
Acum stiam de ce crapa, da nu-mi rezolva problema, si anume sa pot folosi toate discurile din sistem.
Si mi-am adus aminte ca atunci cand am mai avut probleme din astea cand nu mergeau mai multe lucruri in acelasi timp in kernel am folosit VM-uri se separ pe caprarii componentele.
Asa am ajuns ca pentru fiecare disc pe care trebuie sa-l export sa fac cate o masina cu KVM la care sa-i atasez discul din host, sa fac cate o configuratie simpla de ISCSI target si s-o prezint mai departe la ESXi-uri. E o solutie scarpinata pe dupa ureche, da’ merge si pentru ca virtualizare si discuri din host in VM direct, nu se observa nici un overhead.
Nu e cea mai eleganta solutie, dar merge fara prea mult efort de administrare.