Шостая версія патчаў для ядра Linux з падтрымкай мовы Rust

Мігель Охеда (Miguel Ojeda), аўтар праекта Rust-for-Linux, прапанаваў для разгляду распрацоўшчыкамі ядра Linux выпуск v6 кампанентаў для распрацоўкі драйвераў прылад на мове Rust. Гэта сёмая рэдакцыя патчаў з улікам першага варыянта, апублікаванага без нумара версіі. Падтрымка Rust разглядаецца як эксперыментальная, але ўжо ўключана ў галінку linux-next і дастаткова развіта для пачатку працы па стварэнні пластоў абстракцыі над падсістэмамі ядра, а таксама для напісання драйвераў і модуляў. Распрацоўка фінансуецца кампаніяй Google і арганізацыяй ISRG (Internet Security Research Group), якая з'яўляецца заснавальнікам праекта Let's Encrypt і садзейнічае прасоўванню HTTPS і развіццю тэхналогій для павышэння абароненасці інтэрнэту.

У новай версіі:

  • Інструментарый і варыянт бібліятэкі alloc, пазбаўлены ад магчымых генерацый стану "panic" пры ўзнікненні памылак, абноўлены да выпуску Rust 1.60, у якой стабілізаваная падтрымка рэжыму "maybe_uninit_extra", які ўжываецца ў патчах да ядра.
  • Дададзена магчымасць выканання тэстаў з дакументацыі (тэсты, адначасова выкарыстоўваныя ў якасці прыкладаў у дакументацыі), праз пераўтварэнне падчас кампіляцыі тэстаў, завязаных на API ядры, у тэсты KUnit, выкананыя падчас загрузкі ядра.
  • Прыняты патрабаванні, у адпаведнасці з якімі тэсты не павінны прыводзіць да высновы папярэджання лінтара Clippy, як і код для ядра на мове Rust.
  • Прапанавана пачатковая рэалізацыя модуля «net» з сеткавымі функцыямі. Для кода на мове Rust прадстаўлены доступ да такіх сеткавых структур ядра, як "Namespace" (на аснове структуры ядра "struct net"), SkBuff (struct sk_buff), TcpListener, TcpStream (struct socket), Ipv4Addr (struct in_addr), SocketAddrV4 ( struct sockaddr_in) і іх эквівалентам для IPv6.
  • Рэалізавана пачатковая падтрымка метадаў асінхроннага праграмавання (async), рэалізаваная ў форме модуля kasync. Напрыклад, можна ствараць які працуе ў асінхронным рэжыме код для маніпуляцыі з TCP-сокетамі: async fn echo_server(stream: TcpStream) -> Result { let mut buf = [0u8; 1024]; loop { let n = stream.read(&mut buf).await?; if n == 0 { return Ok(()); } stream.write_all(&buf[..n]).await?; } }
  • Дададзены модуль net::filter для маніпуляцыі з фільтрамі сеткавых пакетаў. Дададзены прыклад rust_netfilter.rs з рэалізацыяй фільтра на мове Rust.
  • Дададзена рэалізацыя простага м'ютэкса smutex::Mutex, які не патрабуе прывязкі (pinning).
  • Дададзена блакіроўка NoWaitLock, якая ніколі не прыводзіць да чакання вызвалення, а ў выпадку занятку іншым струменем прыводзіць да высновы памылкі пры спробе атрымання блакавання замест прыпынку выклікалага.
  • Дададзена блакіроўка RawSpinLock атаясамленая з raw_spinlock_t у ядры, якая ўжываецца да секцый, якія не могуць знаходзіцца ў стане чакання.
  • Дададзены тып ARef для спасылак на аб'ект, да якога прымяняецца механізм падліку спасылак (always-refcounted).
  • У бэкендзе rustc_codegen_gcc, які дазваляе выкарыстоўваць бібліятэку libgccjit ад праекта GCC у якасці генератара кода ў rustc для забеспячэння ў rustc падтрымкі даступных у GCC архітэктур і аптымізацый, рэалізаваная магчымасць раскруткі кампілятара (bootstrapping) rustc. Пад раскруткай кампілятара разумеецца магчымасць выкарыстання ў rustc генератара кода на аснове GCC для зборкі самага кампілятара rustc. Акрамя таго, у нядаўні выпуск GCC 12.1 уключаны выпраўленні ў libgccjit, неабходныя для карэктнай працы rustc_codegen_gcc. Вядзецца падрыхтоўка да прадастаўлення магчымасці ўстаноўкі rustc_codegen_gcc пры дапамозе ўтыліты rustup.
  • Адзначаецца прагрэс распрацоўкі GCC-франтэнду gccrs з рэалізацыяй кампілятара мовы Rust на базе GCC. У цяперашні час над gccrs ў рэжыме поўнага працоўнага для працуюць два распрацоўшчыкі.

Нагадаем, што прапанаваныя змены даюць магчымасць выкарыстоўваць Rust у якасці другой мовы для распрацоўкі драйвераў і модуляў ядра. Падтрымка Rust падаецца як опцыя, не актыўная па змаўчанні і не якая прыводзіць да ўключэння Rust у лік абавязковых зборачных залежнасцяў да ядра. Выкарыстанне Rust для распрацоўкі драйвераў дазволіць з мінімальнымі намаганнямі ствараць бяспечныя і больш якасныя драйверы, пазбаўленыя ад такіх праблем як зварот да вобласці памяці пасля яе вызвалення, разнайменаванне нулявых паказальнікаў і выхад за межы буфера.

Бяспечная праца з памяццю забяспечваецца ў Rust падчас кампіляцыі праз праверку спасылак, адсочванне валодання аб'ектамі і ўлік часу жыцця аб'ектаў (вобласці бачнасці), а таксама праз адзнаку карэктнасці доступу да памяці падчас выканання кода. Rust таксама дае сродкі для абароны ад цэлалікіх перапаўненняў, патрабуе абавязковай ініцыялізацыі значэнняў зменных перад выкарыстаннем, лепш апрацоўвае памылкі ў стандартнай бібліятэцы, ужывае канцэпцыю нязменнасці (immutable) спасылак і зменных па змаўчанні, прапануе моцную статычную тыпізацыю для мінімізацыі лагічных памылак.

Крыніца: opennet.ru

Дадаць каментар