perjantai 17. helmikuuta 2012

Ristiretki linuxkehittäjien maailmaan.

Aiemmin kirjoittelin pienen pätkän netlink soketeista, ja linuxin IP-pinkan konfiguroinnista niiden avulla. Tuota konfigurointityötä itse tehdessäni huomasin IPv6 pinkan toiminnan poikkeavan IPv4 pinkan toiminnasta. RFC 3549 määrittelee netlink requesteille mm. liput NLM_F_CREATE, NLM_F_REPLACE, NLM_F_MATCH ja NLM_F_EXCL liput, joiden toteutus (reititysten osalta) IPv6 pinkasta puuttui. (NLM_F_MATCH lipun toteutus puuttui myös IPv4 pinkasta - ja puuttuu edelleen kernelversion 3.3-RC3 ollessa uusin julkaistu versio.)

Päätin että no hittolainen, jos ei vuorta ole, niin Muhammed voi tarttua lapioon. Onhan linux sentään avoin systeemi. Toisin sanoen, kokosin kaiken päättäväisyyteni, ja totesin että vielä näemme minunkin nimeni Linuxin kehittäjien pitkässä listassa. Ja sinnehän se lopulta päätyi ( siellä se on, neljällä patchilla :) http://www.remword.com/kps_result/3.3_ftc.html ), mutta pakko myöntää, tuo polku ei ollut ihan niin sileä kuin voisi kuvitella... Mutta jotta joku toinen voisi jättää jonkin umpikujan koluamatta, niin kuvaan hieman omaa aherrustani.

Siispä ensin tarvitaan itse pihvi, eli linuxin kerneli. Riensin kipin kapin www.kernel.org osoitteeseen, ja latasin tuoreimman kernelpaketin etusivulta.
Seuraavat pari päivää olivat intensiivistä tutkimista, IPv6 pino / FIB - tietorakenne (Forwarding Information Base jossa reitit ovat tallessa) kun eivät olleet alkuunkaan tuttuja.

Jossain kohtaa tuli mieleeni, että hetkonen, olenkohan todellakin ensimmäinen joka huomaa puutteen pinkassa. Ehkäpä siihen on jokin syy miksi tuota tukea ei pinkasta löydy...

Nyt oli siis tarpeen selvittää, miten muutos oikein kerneliin saataisiin, kuka muutosten hyväksynnästä päättää, ja kuka oikeastaan tekee kernelpaketit... ???

Linuxin lähdekoodien joukosta löytyy MAINTAINERS tiedosto, jossa periaatteessa kerrotaan kuka vastaa mistäkin kernelin osasesta. Viimekädessä muutokset varsinaiseen linux kerneliin hyväksyy tai hylkää linuxin alkuperäinen kehittäjä, Linus Torvalds. Ja koko linux kerneliä koskevat keskustelut käydään lkml - maililistalla (Linux Kernel Mailing List). Itse asiassa, hyvin pitkään Linus itse valvoi vielä tarkemmin kaikkia muutoksia, siis KAIKKIA MUUTOKSIA. Nykyään kernel on kuitenkin jaettu eri osa-alueisiin, ja useilla osa-alueilla on oma "maintaineri" ja maililista, jossa käsitellään kyseiselle alueelle kohdistuvat muutokset. Jokaisella osa-alueella on oma versionhallinta, johon muutoksia tehdään. Tietyin väliajoin kaikkien eri osa-alueiden lähdekoodipuut sitten yhdistetään eli "mergetään" linusin puuhun, ja linus tekee omasta puustaan linux releasen. Tai itse asiassa, ei ihan näin suoraviivaisesti..

Yhtä kaikki, IP pino kuului siis netdev osioon, jossa maintainerina on David Miller. Netdevin maililista löytyy osoitteesta netdev@vger.kernel.org. Tässävaiheessa olin jo lukenut, että maililistalla on *hyvin* tarkat säännöt siitä, miten tulee toimia - varsinkin jos aikoo saada jonkin muutoksen läpi... Ensinnäkin, turhia kysymyksiä kannattaa välttää. Siispä koetin ensin läpikäydä lkml ja netdev listojen "archiveita" jotta löytäisin josko joku oli jo asiasta kysellyt. Mutta kun en mitään osuvaa löytänyt, kirjoitin kysymyksen että onko lippujen huomiotta jättämiseen jokin syy. (alkuperäiset mailit täällä http://comments.gmane.org/gmane.linux.network/208853 ). Viimein sain muutaman rivin vastauksen, kertoen että IPv6 pinosta vain puuttui yhä muutamia IPv4 pinoon tehtyjä ominaisuuksia, ja että patchi - eli siis tietynmuotoinen koodimuutos - oli tervetullut.

Niinpä muokkasin kerneliä ja testailin muutoksia. Viimein olin mielestäni saanut toimivan kernelin aikaiseksi, joka kiltisti kunnioitti NLM_F_CREATE, NLM_F_REPLACE ja NLM_F_EXCL lippuja. Eli uusien reittien luonti ilman NLM_F_CREATE lippua estettiin, NLM_F_EXCL lipulla varustettu luonti estettiin jos jokin olemassaoleva reitti oli ristiriidassa luotavan kanssa, ja NLM_F_REPLACE lipulla varustetlla pyynnöllä pystyi korvaamaan ristiriitaisen reitin. Eipä siis muuta kuin patchin tekoon.

Koska en ollut ennemmin itse tehnyt patcheja (nähnyt kyllä olin), turvauduin jälleen (onneksi) googleen. Pian minulle selvisi, että linuxiin aiottu patchi tuli tehdä tietyssä formaatissa, tai maintainer luultavasti tipauttaisi patchin ilman erillisiä kommentteja. oikea loitsu olisi

diff -uNr > patchitiedosto.patch

Lisäksi minulle selvisi, että linuxiin aiotut koodit tulisi muotoilla tietyn "standardin" mukaan. Tämän muotoilun tarkistamiseksi kernelin mukana tulevassa scripts kansiossa on oma checkpatch.pl skripti, jolla patchi voidaan tarkistaa... Tein siis patchin, ja ajoin ko. skriptin...

... muistinko mainita että minulla on aina ollut jokseenkin omintakeinen tyyli kirjoittaa koodia...

lopputuloksena muutaman sadan rivin patchista löytyi useampi sata virhettä...

Tässä vaiheessa meinasin tiputtaa hanskat, ja jättää kaiken sikseen. Olin kuitenkin aiemmin päättänyt että nimeni vielä olisi kernel kehittäjien listalla... Siispä käärin hihani ja korjasin virheet. Samalla opin myös Signed-Off-By rivin käytön, jolla kehittäjä siis "allekirjoittaa" muutoksensa. Huomasin myös sen, että patchi toivottiin lähetettävän shköpostin mukana tekstinä - ei liitteenä helpomman arvioinnin vuoksi. Ja myös viestin otsikon tulisi sisältää sana [PATCH].

ei siis muuta kuin muutaman rivin runo postin alkuun, patchin pastaus postiin, ja viestiä listalle - maintainer CC kentässä.

Tämän jälkeen seurasi sarja virheitä... Todennäköisesti olin hyyyyvin lähellä päätyä Daven mustalle listalle :)

1. Ensimmäisen patchin lähetin MS outlookilla, joka mutiloi patchini lisäämällä välilyöntejä, rivinvaihtoja jne. Ainakaan yksikään automaattinen patchintestausskripti ei sitä varmasti tuntenut.

Uudelleenlähetin patchin evolution sähköpostilla, preformatted plaintext muodossa, ja tälläkertaa patchi pysyi kuosissa.

Sain Davelta palautetta, että NLM_F_CREATE lipun vaatiminen rikkoisi yhteensopivuuden userspace applikaatioiden kanssa. Muutaman viestin sain joissa ajatusta kiiteltiin, ja herra Shemminger (mm. iproute2 kehittäjä) ehdotti että NLM_F_CREATE lipun puuttuessa, hylkäämisen sijaan printtaisin varoituksen kernel logiin.

2. Lähetin uuden patchin vastaamalla edelliseen viestiini. (Jokainen patchi pitisi olla omassa viestissän, subjecti versionumerolla höystettynä)
3. Davidin huomauttaessa tästä, laitoin saman patchin pelkästään hänelle (Jokainen viesti tulee laittaa listalle).

Lopulta sain patchin listalle. Sain uusia kommentteja mm. muutaman kernel specifisen makron käytöstä, ja pyynnön jakaa patchini kahteen eri osaan.. Tein jälleen pyydetyt muutokset, ja lähetin patchini mailmalle.

Vastausta ei kuulunut. Odotin. Odotin useamman päivän. Lopulta google löysi minulle patchwork.ozlabs.org sivuston, jolle patchini oli ilmestynyt. Tilaksi oli tullut "deferred". Koetin googlailla tietoa siitä, mitä "deferred" tarkoittaa. Lopulta kysyin hermostuneesti asiaa listalla.

4. En luonnollisestikaan antanut riittävän tarkkaa tietoa kysyessäni - kuten esimerkiksi sitä mistä patchista oli kyse :rolleyes: Niinpä kysymykseeni vastattiin kysymyksellä. Linkin patchiin postattuani sain vastauksen, että koska patchini on enemmän uusi ominaisuus kuin vikakorjaus, se menisi net-next puuhun, ei net puuhun, ja että net-next puu oli keskellä merge-ikkunaa jolloin uusia patcheja ei oteta sisään. Minua neuvottiin postaamaan patchini kun merge-ikkuna olisi ohi.

Paaaaljon lisää googlailtavaa. Nyt minulle selvisi, että kriittiset bugikorjaukset menisivät suoraan net-puuhun, joka yhdistettäisiin heti seuraavaan viralliseen linuks versioon. Eli seuraavaan release-kandidaattiin. Uudet ominaisuudet ja muut muutokset joilla on mahdollisuus rikkoa olemassaolevaa toiminnallisuutta menevät net-next puuhun, joka yhdistetään joka päivä linux-next testauspuuhun - joka yhdistetään seuraavan kokonaan uuden linuxversion pohjaksi. Eli esim. tällähetkellä viimeisin ulos tullut "oikea" linux versio on 3.2. Tällähetkellä tekeillä on 3.3 versio. 3.3 versiota kehitettäessä välietappeina tehdään 3.3-rcX versioita, joissa X siis kasvaa. (rc - release candidate). net-puuhun tehdyt muutokset yhdistetään välittömästi seuraavaan 3.3-rc releaseen, ja on täten mukana heti kun lopullinen linux 3.3 saadaan valmiiksi. net-next puuhun tehdyt muutokset yhdistetään päähaaraan kun linux 3.3 on saatu tehtyä, ja linux 3.4:n teko aloitetaan release candidate 1:llä (linux 3.4-rc1).

Merge ikkuna tarkoitti siis sitä, että net-next puuta oltiin juuri yhdistämässä uuden linux 3.2-rc1:n pohjaksi, ja uusia muutoksia net-nextiin ei vastaanotettaisi ennen kuin 3.2-rc1 olisi onnistuneesti yhdistetty kaikkien linux osa-alueiden maintainereiden puista.

Tätä puuttuvaa tiedon palasta siitä, milloin merge -ikkuna päättyisi en löytänyt... Löysin kyllä vastaavan termin u-bootin kehittäjien listalta. Niinpä linux 3.2-rc1:n ilmestyttyä kernel.org sivulle,

5. kysyin netdevin listalla olisiko merge-ikkuna nyt sulkeutunut....

Viides virheeni melkein kaatoi Daven kupin :] Sain melko tulisen vastauksen, että minun kannattaisi ehkä seurata heidän maililistaansa, eikä kysellä typeriä. Dave oli juuri edellisenä päivänä laittanut listalle viestin, jossa ilmoitti megre-ikkunan sulkeutuneen... En vielä tänäkään päivänä ymmärrä miten tuo viesti jäi minulta näkemättä. (Olin siis seurannut netdev listaa jo useamman viikon ajan).

Tässävaiheessa olisin halunnut kysyä, että miten minun tulisi nyt muotoilla subject rivi patchiviestilleni, koska patchihan olisi uudelleenlähetys... En kuitenkaan tehnyt sitä, vaan kahlasin läpi maililistan archiveita katsellen, kuinka muut olivat uudelleenlähetykset merkanneet. Päädyin lisäämään RESUBMIT sanan ja versionumron PATCH - sanan perään. Ilmeisesti tapa oli Ok, koska hiljaisuuden jälkeen sain viestin että patchini oli hyväksytty net-next puuhun. JIPPII!!

Ja vain muutamaa tuntia myöhemmin sain viestin, että jokin koodicheckeri oli havainnut patchissani mahdollisen bugin. Muuttuja tarkastettiin NULL:in varalta, mutta myöhemmin sitä käytettiin tarkistuksen tuloksesta riippumatta. Tutkin tilannetta ja totesin, ettei muuttuja voisi mitenkään olla invalidi, joten NULL tarkistus oli siinäkohtaa turha. Laitoin listalle vastauksen, generoin uuden patchin jossa NULL tarkisus poistettiin, ja lähetin sen listalle.

Tämän jälkeen latasin ihan uuden kernelversion, ajoin patchini, käänsin ja käynnistin PC:ni ajamaan näin syntynyttä uutta kerneliä. Jätin muutaman testin ajoon ja kävin tyytyväisenä nukkumaan...
...Seuraavana päivänä totesin kernelini kaatuneen. Kylmä hiki nousi otsalleni. Nyt viimesitään olisin mustalla listalle ikuisesti. Pikainen tutkimus, ja huomasin virheeni. Eräästä gotohaarasta puuttui tarkistelu, joten sopivassa tilanteessa yritys korvata olematon reitti aiheuttaisi FIB-rakenteen korruptoitumisen ja kaatumisen kun rakennetta seuraavan kerran accessoitaisiin.. Tein pikapikapikaseen uuden patchin, ja laitoin sen menemään. Yllätyksekseni ainoa vastaus oli, että "patch accepted". Kylmän viilean asiallinen. Ikäänkuin kuittaus että "virheitä sattuu". Ei syyllisten etsintää. Ei syyttömien rankaisua. Vain asian hoitaminen.

Ja siinä se. Koko 3.2 kernelin kehityksen ajan muutokseni istui net-next puussa, päätyen tuolla aikaa jokaiseen linux-next testibuildiin, ja luultavasti joidenkin kokeilunhaluisten käyttäjien koneisiinkin. 3.2:n valmistuttua, 3.3-rc1:n mergeäminen alkoi, ja muutokseni ui net-next puusta mm. Linus Torvaldsin "viralliseen linux puuhun", samoin kuin linux-2.6 puuhun. Tällähetkellä muutokseni on siis ollut mukana linux 3.3-rc1, 3.3-rc2 ja 3.3-rc3 paketeissa, jotka ovat kaikki olleet ladattavissa kernel.org sivustolta. Luultavasti muutokseni on siis uinut jo useiden kokeilunhaluisten koneille. Aikanaan lopullisen 3.3 julkaisun valmistuessa, muutokseni päätynee myös tunnettujen linux-distribuutioiden ytimiin. Fedoraan, Ubuntuun, SuSeen... Kenties sinunkin koneellesi, reitittimelesi, kahvinkeittimeesi...?

Ei kommentteja: