Почему API модуля Linux не имеет обратной совместимости?
Почему API модуля Linux не имеет обратной совместимости? Я разочарован, обнаружив обновленные драйверы после обновления ядра Linux.
У меня есть беспроводной адаптер, для которого нужен проприетарный драйвер, но производитель снял с производства это устройство около 7 лет назад. Поскольку код очень старый и был написан для Linux 2.6.0.0, он не компилируется с последними ядрами Linux. Я использовал много дистрибутивов Linux, но везде одна и та же проблема. Хотя с ядром Linux распространяется драйвер с открытым исходным кодом, он не работает. Некоторые люди пытаются изменить старый проприетарный код, чтобы сделать его совместимым с последними ядрами Linux, но когда выпускается новое ядро Linux, требуются месяцы, чтобы сделать код совместимым с ним. За это время выходит еще одна новая версия. По этой причине я не могу перейти на новое ядро Linux; иногда я даже не могу обновить свой дистрибутив.
Ответы
Грег Кроа-Хартман написал на эту тему здесь: https://www.kernel.org/doc/html/v4.10/process/stable-api-nonsense.html
Помимо некоторых технических деталей, касающихся компиляции кода C, он выделяет пару основных проблем разработки программного обеспечения, которые принимают решение.
Ядро Linux - это всегда работа. Это происходит по многим причинам:
- Появляются новые требования. Люди хотят, чтобы их программное обеспечение было больше, поэтому большинство из нас обновляется, нам нужны новейшие и лучшие функции. Это может потребовать доработки существующего программного обеспечения.
- Обнаружены ошибки, требующие исправления, иногда ошибки связаны с самим дизайном и не могут быть исправлены без значительной доработки.
- В мире программного обеспечения появляются новые идеи и идиомы, и люди находят гораздо более простые / элегантные / эффективные способы сделать что-то.
Это верно для большинства программ , и любое программное обеспечение, которое не поддерживается, умрет медленной и мучительной смертью . Вы спрашиваете, почему этот старый неподдерживаемый код до сих пор не работает?
Почему не обслуживаются старые интерфейсы?
Для обеспечения обратной совместимости потребуется поддерживать старые (часто «сломанные» и небезопасные) интерфейсы. Конечно, теоретически это возможно, за исключением того, что это требует значительных затрат .
Грег Кроа-Хартман пишет
Если бы Linux нужно было гарантировать, что он сохранит стабильный исходный интерфейс, был бы создан новый интерфейс, а старый, сломанный, пришлось бы поддерживать с течением времени, что привело бы к дополнительной работе для [разработчиков]. Поскольку все [разработчики] Linux выполняют свою работу в свободное время, просить программистов выполнять дополнительную работу без всякой выгоды и бесплатно - невозможно.
Несмотря на то, что Linux является открытым исходным кодом, у разработчиков все еще есть ограниченное время для его поддержки. Так что о рабочей силе все еще можно говорить с точки зрения «стоимости». Разработчикам предстоит выбрать, как они проводят время:
- Уделите много времени поддержке старых / сломанных / медленных / небезопасных интерфейсов. Иногда это может быть вдвое или втрое больше, чем время, необходимое для написания интерфейса в первом экземпляре.
- Откажитесь от старых интерфейсов и ожидайте, что другие разработчики программного обеспечения [будут выполнять свою работу и] поддерживать свое собственное программное обеспечение.
В целом, интерфейсы биннинга действительно рентабельны (для разработчиков ядра) . Если вы хотите знать, почему разработчики не тратят месяцы и годы своей жизни, спасая вас от оплаты 10 долларов за новый адаптер Wi-Fi ... вот в чем причина. Помните, что это экономически выгодно для разработчиков ядра, но не обязательно для вас или производителей.
Хотя я внес несколько (очень незначительных) исправлений в ядро Linux, я не считаю себя разработчиком ядра. Однако вот что я знаю:
Драйвер, написанный для версии ядра 2.6.0.0, предшествовал устранению большой блокировки ядра (BKL), которая произошла в версии ядра 2.6.39.
BKL был создан еще тогда, когда Linux еще была однопроцессорной (одноядерной, однопоточной) ОС. Как только была добавлена поддержка SMP, разработчики поняли, что BKL в какой-то момент станет большим узким местом, но до тех пор, пока в системе было всего несколько ядер / потоков, это было несколько терпимо. Но сначала это стало настоящей проблемой для людей, использующих Linux в суперкомпьютерах, и поэтому началась работа по замене всего, что требовало BKL, более мелкими механизмами блокировки или, когда это возможно, методами без блокировки.
На современных компьютерах, которые могут иметь двузначное число ядер на обычных настольных компьютерах и мощных портативных компьютерах, не говоря уже о серверах, API модуля ядра с обратной совместимостью 2.6.0 также потребует реализации BKL.
Если унаследованный модуль говорит: «Я хочу взять BKL», остальная часть ядра не имеет ни малейшего представления о том, что модуль планирует с ним делать, и поэтому механизму обратной совместимости придется принять все блокировки, которые заменили BKL. просто чтобы охватить все возможности. Это было бы большим ударом по производительности. И новые методы без блокировки также должны будут проверять устаревшую блокировку, которая в первую очередь лишает смысла отсутствие блокировки. Таким образом, само существование механизма обратной совместимости снизит производительность системы, даже если унаследованные модули не были загружены.
Совсем недавно патчи безопасности Spectre / Meltdown внесли большие изменения в то, что должно происходить при переходе границы между ядром и пользовательским пространством. Любые модули, скомпилированные до того, как были реализованы исправления Spectre / Meltdown, могут быть ненадежными с ядрами после Specre / Meltdown.
Всего две недели назад я устранял неполадки на старом сервере, который требовал выключения и включения питания вручную, когда обновления безопасности применялись автоматически. Это случалось раньше несколько раз, и это можно было воспроизвести. Я обнаружил, что у него была очень старая версия проприетарного megasr
драйвера хранилища, выпущенная до патчей Spectre / Meltdown, которая не была включена в автоматические обновления. После обновления драйвера до актуальной версии проблема исчезла. Кстати, это было в простой системе RHEL 6.10.
Я также видел сбой серверов при загрузке проприетарных драйверов аппаратного мониторинга до Spectre / Meltdown с ядром после Spectre / Meltdown. Основываясь на этом опыте, я полностью убежден, что исправления Spectre / Meltdown следует рассматривать как переломный момент: ядро и модули должны быть либо всеми версиями до исправлений, либо всеми версиями после исправлений; смешивание и сопоставление приведет только к тревоге и полуночным будильникам для дежурного системного администратора.
А поскольку Spectre был проблемой на уровне разработки ЦП , это «подарок, который продолжает дарить»: некоторые люди найдут новые способы использования слабых мест, и тогда разработчикам ядра нужно будет найти способы блокировать эксплойты.
Это всего лишь две большие проблемы, которые необходимо решить API устаревшего модуля ядра, совместимого с 2.6.0.0. Я уверен, что есть много других.
И еще есть более философская сторона. Подумайте об этом: что делает Linux возможным?
Большая часть этого - открытые спецификации оборудования . Если спецификации оборудования открыты, любой может участвовать. Поскольку исходный код операционной системы открыт, каждый может внести свой вклад на благо всех. И вы не можете хранить спецификации аппаратного программирования в качестве коммерческой тайны, если ваш код драйвера является открытым.
Разработчики ядра Linux склонны верить в модель с открытым исходным кодом. Вот почему они сделали свой выбор в области дизайна и разработки, так что предпочтительный способ участия производителя оборудования - это открыть исходный код драйвера, объединить его с основным дистрибутивом исходного кода ядра, а затем (и только тогда ) вы получить выгоду от всего сообщества разработчиков ядра в его поддержке.
Это дает определенный стимул разработчикам и производителям оборудования сделать это возможным. Если у вас есть что-то, что вы хотите сохранить в секрете, постарайтесь инкапсулировать это в ASIC или, возможно, в подписанную прошивку, если необходимо. (Если вы сделаете последнее, предоставьте другим разрешение на распространение пакета микропрограмм.)
Но поскольку ядро имеет открытый исходный код, разработчики ядра не могут помешать другим поддерживать проприетарные драйверы отдельно. Но и у них нет стимула заботиться о них.
Фактически, дополнительные хлопоты, вызываемые проприетарными бинарными драйверами при отладке ядра, являются стимулом для разработчиков ядра не заботиться о разработке проприетарных драйверов: «Они усложняют мою работу, почему я должен делать что-то конкретное, чтобы облегчить их работу?»
Итак, разработчики ядра обычно делают то, что для них как группы / сообщества наиболее выгодно . Если это включает в себя изменение API модуля, пусть будет так. Сторонние драйверы даже не входят в уравнение.