LINUX.ORG.RU

Продемонстрирована возможность разработки частей Linux на Rust

 , ,


4

9

Французский программист написал статью, в которой рассмотрел возможность переписывания ядра Linux на Rust.

В статье отмечено, что данный язык хорошо подходит для системного программирования, будучи достаточно низкоуровневым и при этом лишённым многих недостатков C, и уже используется для написания новых ОС. Однако автор не считает создание ОС с нуля перспективным для серьёзного применения, и последовательный перенос отдельных частей Linux на Rust для решения различных проблем безопасности кажется ему более целесообразным.

В качестве «Proof of Concept» была приведена реализация системного вызова, содержащая вставки на Assembler внутри unsafe-блоков. Код компилируется в объектный файл, не связанный с библиотеками и интегрируемый в ядро во время сборки. Работа производилась на основе исходного кода Linux 4.8.17.

>>> Статья



Проверено: Shaman007 ()
Последнее исправление: sudopacman (всего исправлений: 5)

Ответ на: комментарий от www_linux_org_ru

выставлять первый вариант нельзя, т.к. это нарушает хоть слабенькую, но гарантию «если что-то в программе пошло не так, то виноват именно unsafe код» 

Ваш первый вариант (не проверять условия и не паниковать) без unsafe кода написать нельзя. Про выставление такого варианта наружу я вообще не говорил, я говорил про паникующую функцию и про функцию, возвращающую Result, поскольку отвечал на «что предпочесть: возврат Result-а или иницирование паники.»

red75prim ★★★
()
Ответ на: комментарий от RazrFalcon

Куда смотреть? Вы про то, что мой вариант больше асма нагенерировал?

Дело в том, что он проверяет валидность обращений по индексу, отсюда и больше работы, это из-за UTF-8. Так, что твой пример не эквивалентен.

numas13
()
Ответ на: комментарий от RazrFalcon

А при чём тут utf8? Мой код работает с байтами.

&str может паниковать на операциях выделения слайсов, если граница слайса проходит внутри code point.

red75prim ★★★
()
Ответ на: комментарий от RazrFalcon

Ну ваш тоже не эквивалентен, ибо у вас char, а не u8, как в C++.

Да, но в данном случае это не важно, т. к. мы проверяем работу контейнера. Замена char на u8 не отразится на этом примере.

numas13
()
Ответ на: комментарий от eao197

Увеличение количества работы.

На 3 строки.

fn may_fail() -> Result {
    // do stuff
    if error_happened {
        Err("Oops :(")
    } else {
        Ok(data)
    }
}

fn may_fail_panicking() {
    may_fail().unwrap()
}

mersinvald ★★★★★
()
Последнее исправление: mersinvald (всего исправлений: 2)
Ответ на: комментарий от eao197

А расскажите про свое знакомство с Rust-ом? Вы коммерческие проекты на нем делаете? Или OpenSource? Или hello_world-ы для себя?

Буквально пару месяцев назад (может больше) стал изучать Rust, прошёлся по документации с оф.сайта и по проектам на github. Пару недель назад на работе начал проект для IoT, пока полёт нормальный. Язык нравиться, библиотек достаточно, огорчает отсутствие IDE, но хватает Visual Studio Code.

Есть фирмы которые ведут основную разработку на Rust, точно знаю о Рестрим которое подразделения Ростелекома.

AntonyRF ★★★★
()
Ответ на: комментарий от AntonyRF

подразделение

И почему я не могу редактировать свои сообщения?!

AntonyRF ★★★★
()
Ответ на: комментарий от eao197

Но если уж Федя возвращает Result, то с какого перепугу пользователь должен думать о паниках из-за нарушения инвариантов внутри Фединого кода.

Вот именно, что не должен думать. Паники сами о себе напомнят и простимулируют пользователя Васю идти пинать автора Федю, чтобы плюсы с минусами не путал, инварианты не нарушал и тестировал код тщательнее.

А про то, как обработать Err(CustomError::Code(12)), и понять, что это - баг в Фединой библиотеке, нужно будет думать Васе.

red75prim ★★★
()
Ответ на: комментарий от www_linux_org_ru

Ты не можешь это сделать без ансейфа мутабельно: компилятор никак не может в компилтайме гарантировать что твои рантаймовые значения не вызовут создания перекрывающихся мутабельных срезов (что небезопасно).

Иммутабельно — наздоровье.

mersinvald ★★★★★
()
Ответ на: комментарий от red75prim

Резюмируя, паники нужны для обозначения критических ошибок, которые НЕ ДОЛЖНЫ произойти (деление на ноль, кончилась память, ошибка свидетельствует о баге внутри библиотеки).

Result — для ожидаемых ошибок, которые пользователь библиотеки может обработать (обрыв соединения, неверный инпут)

mersinvald ★★★★★
()
Ответ на: комментарий от red75prim

Не знал. Думал там только проверка границ есть.

RazrFalcon ★★★★★
()
Ответ на: комментарий от mersinvald

ты мне напомнил анекдот советских времен про японцев:

один японец приходит к другому и говрит:

 — угадай, что у меня в кулаке зажато!
 — телевизор!
 — правильно, телевизор! а сколько их?

так и тут; правильно, unsafe; а сколько их?

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от mersinvald

На 3 строки.

Поскольку ваши проекты не вышли за пределы hello_world-а и не развиваются по нескольку лет подряд, то вы легкомыслено относитесь к тому, без чего хотелось бы обойтись.

eao197 ★★★★★
()
Ответ на: комментарий от red75prim

Вот именно, что не должен думать.

И как тогда жить Васе, если он не знает, какие паники из Фединой библиотеки вылетают? Исходить из того, что жопа все равно может случиться и без разницы какая именно?

Блин, так тогда и Result может идти лесом, мы же рассчитываем лишь на хороший случай.

А про то, как обработать Err(CustomError::Code(12)), и понять, что это - баг в Фединой библиотеке, нужно будет думать Васе.

Етить-колотить, а разве это не главный аргумент в руках растоманов, которых C++ные исключения покусали: мол, коды ошибок — это очевидно и понятно?

Да, Вася получит от Фединой библиотеки код ошибки, может быть сделает какой-то откат операции у себя, но продолжит работу далее нормально. Вместо краха и рестарта.

eao197 ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

пойнт в том, что за безопасность надо платить слишком много

Пойнт в том, что «слишком много» без бенчмарков и контекста ничего не значит.

red75prim ★★★
()
Ответ на: комментарий от AntonyRF

Ну т.е. без году неделя. И проекту столько же. Рисков от смены языка и имеющихся наработок на Rust никаких.

точно знаю о Рестрим которое подразделения Ростелекома.

Да там очень эффективно пилят государственные деньги и проекты отданы на откуп молодым хипстерам, которые могут выбирать для себя все, что угодно. Хоть Go, хоть Rust.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Етить-колотить, а разве это не главный аргумент в руках растоманов, которых C++ные исключения покусали: мол, коды ошибок — это очевидно и понятно?

Коды ошибок никто не использует. Возвращают enum'ы, которые ещё и значения разные содержать могут.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

их нужно и можно редактировать без копирования целых строк — т.е. чтобы всегда х1 и х2 были частью х, а у1 и у2 частью у

#include <iostream>

struct String
{
  char* start;
  int length;
  String(char* start, int length): start(  start), length(  length) {}
  String(const String& s):         start(s.start), length(s.length) {}
  
  String& operator= (const String& that) /// копирует из that в this максимально возможное к-во символов
  {
    for( int i=0; i<this->length && i<that.length; ++i )
    {
      this->start[i] = that.start[i];
    }
    return *this;
  }
};



std::ostream& operator << ( std::ostream& out, const String& s )
{
  for( int i=0; i<s.length; ++i )
  {
    out << s.start[i];
  }
  return out;
}

std::pair<String,String> inplace_split_x_by_length_of_y1_and_y2( String x, String y1, String y2 )
{
  return std::make_pair( String(x.start,y1.length), String(x.start+y1.length,y2.length) );
}

const int k=2;
const int l=3;

char u[k+l] = {'1','2','3','4','5'};
char v[k+l] = {'a','b','c','d','e'};

int main()
{
  String x (u,  k+l);
  String y (v,  k+l);
  String y1(v  ,k);
  String y2(v+k,l);
  std::pair<String,String> x1x2 = inplace_split_x_by_length_of_y1_and_y2( x, y1, y2 );
  String x1 = x1x2.first;
  String x2 = x1x2.second;

  std::cout << x1 << " " << x2 << ' ' << x << "\n";
  std::cout << y1 << " " << y2 << ' ' << y << "\n";

  x1=y1;

  std::cout << x1 << " " << x2 << ' ' << x << "\n";
  std::cout << y1 << " " << y2 << ' ' << y << "\n";

  y2=x2;
  
  std::cout << x1 << " " << x2 << ' ' << x << "\n";
  std::cout << y1 << " " << y2 << ' ' << y << "\n";

  x1=x2;

  std::cout << x1 << " " << x2 << ' ' << x << "\n";
  std::cout << y1 << " " << y2 << ' ' << y << "\n";

  y2=y1;

  std::cout << x1 << " " << x2 << ' ' << x << "\n";
  std::cout << y1 << " " << y2 << ' ' << y << "\n";

  
  return 0;
}

выхлоп:

12 345 12345
ab cde abcde
ab 345 ab345
ab cde abcde
ab 345 ab345
ab 345 ab345
34 345 34345
ab 345 ab345
34 345 34345
ab ab5 abab5

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от eao197

Ну т.е. без году неделя. И проекту столько же. Рисков от смены языка и имеющихся наработок на Rust никаких.

Две недели (= Риски всё равно есть, допустим я уволюсь, а кто это будет поддерживать?!

Да там очень эффективно пилят государственные деньги и проекты отданы на откуп молодым хипстерам, которые могут выбирать для себя все, что угодно. Хоть Go, хоть Rust.

Хах, как раз на прошлой недели у них весела вакансия по Go и ещё одна по Rust. Спорить не буду о распилах, но сам факт того что хипстеры в ростелекоме уже взялись за Rust говорит только о том, что язык перспективен КМК.

AntonyRF ★★★★
()
Ответ на: комментарий от red75prim

Пойнт в том, что «слишком много» без бенчмарков и контекста ничего не значит.

ну а что мелочиться? давай сразу с явой бенчмаркать — всего-то в 2 раза медленнее и в 3 раза больше памяти; и зачем тогда этот раст с его непонятным borrow checker-ом?

конечно, мой пример дорабатывать надо — это я навскидку выкатил

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от AntonyRF

Естественно риски не такие как у MS, но в перспективе 6 чел\мес работы терять тоже не хорошо.

AntonyRF ★★★★
()
Ответ на: комментарий от O02eg

А теперь то же самое, только с utf8.

мне не нужно с утф8

мне надо именно байты месить (там на самом деле сложнее конечно, в т.ч. битовые строки, но точно не утф8)

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от RazrFalcon

Вы бы это red75prim-у объяснили, а то у него есть возражения:

А про то, как обработать Err(CustomError::Code(12)), и понять, что это - баг в Фединой библиотеке, нужно будет думать Васе.

И суть этих возражений вовсе не в том, кодом ошибки ли это обозвали или возвращаемым значением.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Исходить из того, что жопа все равно может случиться и без разницы какая именно?

По-моему, тут кто-то не тот думает, что Rust - серебряная пуля.

Что в мире С++ делают, используя сторонние библиотеки? Доверяй, но проверяй. Если падение программы недопустимо, ставь перехват паники, и перемалывай дальше возможно невалидные данные.

коды ошибок — это очевидно и понятно? [...] Вместо краха и рестарта.

Ну уже ведь говорили про это месяца два назад. Принцип fail-fast вполне применим в определённых условиях. Поэтому рассуждать хорошо это или плохо в глобальном философском смысле, без учета конкретных обстоятельств - ни к чему полезному не приведёт.

Марафон по третьему кругу - это уже тяжеловато.

red75prim ★★★
()
Ответ на: комментарий от RazrFalcon

Очень сильно изменится. Но вам не понять.

ну а вдруг кто-то, Достойный Тайного Эзотерического Знания О Колоссальной Разнице забредет на этот форум, прочтет и поймет?

так что ждем объяснения

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от AntonyRF

Спорить не буду о распилах, но сам факт того что хипстеры в ростелекоме уже взялись за Rust говорит только о том, что язык перспективен КМК.

Часть государственных проектов распределяется только между подрядчиками типа Ростелекома. А исполнением этих проектов, на безальтернативной, по сути, основе, занимаются дочки, вроде Рестрима. Причем там у них хорошо то, что даже если затянут сроки и налажают с качеством, то по шапке исполнители получат, но проект не закроют и никому не передадут.

Ну и, собственно, я лично уже давно не говорю, что Rust безперспективный. Но у меня, скажем так, риски чуть повыше. Поэтому «бросить все и начать писать на Rust» сейчас не вариант. А вот послушать впечатления и позадавать неудобные вопросы — это очень интересно, приобщает к пониманию того, как следует Rust использовать и что от этого можно получить.

eao197 ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

Данный код - абсолютный unsafe в терминах rust'a. Ибо раст позволяет иметь только одну мутабельную ссылку на объект. А у вас их 100500 и никакого контроля за ними нет.

Поэтому повторять его смысла нет.

RazrFalcon ★★★★★
()
Ответ на: комментарий от red75prim

Что в мире С++ делают, используя сторонние библиотеки? Доверяй, но проверяй.

Узнают, какой базовый тип у исключений этой библиотеки. И на границах ее использования делают try-catch (ну или ставят try-catch еще выше, там, где есть возможность преодолеть последствия ошибки).

Поэтому в C++, если работа с исключениями разрешена, нет такой дилеммы как выбор между возвращаемым значением и исключением: контракт нарушен — исключение.

В Rust-е, даже по этой ветке, видны сильно разные взгляды. Хотя, казалось бы, за счет Result-а в Rust-е должна быть более сильная унификация.

Вот это и удивляет.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Поэтому «бросить все и начать писать на Rust» сейчас не вариант.

В нашей конторе решили, что на Rust небольшие проекты или либы для больших проектов с нуля делать можно. И только если нет готового решения на С\С++\Delphi. И есть уговор, что если возникнет проблема с которой не поможет сообщество Rust, то переписываем на С\С++\Delphi.

Вариант переписать хотя бы среднего размера проект на С\С++\Delphi в Rust даже не рассматривался.

А вот послушать впечатления и позадавать неудобные вопросы — это очень интересно

Боюсь, что пока у народа мало опыта чтобы отвечать на неудобные вопросы. Сомневаюсь, что тут есть любители Rust со стажем более года акромя RazrFalcon и mersinvald.

AntonyRF ★★★★
()
Ответ на: комментарий от AntonyRF

Сомневаюсь, что тут есть любители Rust со стажем

Любителей со стажем здесь овердофига. А вот тех, кто делает что-то более-менее серьезное, фактически и нет.

eao197 ★★★★★
()
Ответ на: комментарий от RazrFalcon

Ибо раст позволяет иметь только одну мутабельную ссылку на объект. А у вас их 100500 и никакого контроля за ними нет.

и где ж там 100500? реально там 2 объекта х и у с двумя подобъектами каждый

если бы было k=2, l=4 то это примерно как

Struct S { short s1; int s2;};
S* x = new S;
S* y = new S;
short* x1 = &(x->s1);
short* y1 = &(y->s1);
int*   x2 = &(x->s2);
int*   y2 = &(y->s2);

и никакого контроля за ними нет.

есть

с самого начала я сказал, что длины х и у равны, х1 и у1, х2 и у2

это, в общем-то, подобъекты, только с длиной, известной в рантайме (а в коде на с++ это я не выразил как следует, там k и l константы)

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 5)
Ответ на: комментарий от www_linux_org_ru

Это сейчас два. А может быть сколько угодно.

RazrFalcon ★★★★★
()
Ответ на: комментарий от AntonyRF

Мой опыт - 9 месяцев + 20-30К строк кода. Большая часть из которых на github'e и успешно используется кучей людей.

RazrFalcon ★★★★★
()
Ответ на: комментарий от mersinvald

Ну вы бы читали тему читали, уже написано было: нужно тестировать, документировать и сопровождать.

На проектах, которые длятся несколько лет и на которых люди меняются, это все дополнительная работа.

eao197 ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

т.е. существуют языки, для которых твои утверждения неверны

Дык, им приходится идти на другие компромиссы, разве не так?

DarkEld3r ★★★★★
()
Ответ на: комментарий от eao197

Любителей со стажем здесь овердофига. А вот тех, кто делает что-то более-менее серьезное, фактически и нет.

я по-другому на этот вопрос смотрю

допустим, кто-то последние 5 лет пишет исключительно на расте какую-то вычислительную математику, где все, что нужно от указателей — это динамически аллоцировать массив и ходить по нему; и что с этого серьезного человека будет толку?

это я к тому, что если уж переходить на раст, то надо знать, как там делать ооп, шаблоны, исключения и замес байтов, т.е. как перейти на раст не меняя парадигму

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от RazrFalcon

Кстати, может подскажете? Мучает такой вопрос. Допустим есть либа написанная на Си, я дёргаю из неё функции Foo, а в этой функции происходит деление на нуль или обращение к невалидному указателю. Как мне обработать этот ексептион?

AntonyRF ★★★★
()
Ответ на: комментарий от eao197

нужно тестировать

Оборачиваемую функцию? Да, в любом случае нужно.
Зачем тестировать unwrap, который уже протестирован в stdlib?

нужно документировать

// Like may_fail but panicking on error

нужно сопровождать

Обертке не всё равно только на имя и на тип аргументов. Что тут сопровождать?

mersinvald ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

это я к тому, что если уж переходить на раст, то надо знать, как там делать ооп, шаблоны, исключения и замес байтов, т.е. как перейти на раст не меняя парадигму

Я тут сильно не соглашусь. Как сказал Алан Перлис: «язык, который не меняет стиля мышления, не заслуживает внимания».

Не вижу смысла переходить на Rust для того, чтобы делать там ООП, шаблоны и пр. в рамках привычных парадигм. Использовать что-то новое (тот же Rust или Go) имеет смысл если идиоматические для этого нового языка подходы дают существенный выигрыш в решении каких-то задач. Или дают какие-то важные бонусы (вроде повышения безопасности), что может быть важно в каких-то областях.

Если при этом нужно будет перестроить мозги, ну значит нужно будет перестроить. Чтобы затем писать на Rust-е, как на Rust-е, а не как на Java или на C++.

eao197 ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

ооп, шаблоны, исключения
как перейти на раст не меняя парадигму

Никак

mersinvald ★★★★★
()
Ответ на: комментарий от mersinvald

// Like may_fail but panicking on error

Ну, с такими требованиями к уровню документации не мудрено, что вы меня не понимаете. Кто-то за такую «документацию» по рукам нерадивым документаторам бьет.

eao197 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.