К вопросу о Linux (Л)
Мы исходим из того, что вы получаете полноценную операционную систему, сразу полностью за все заплатив. (Билл Гейтс в ответ на вопрос о конкуренции с Л.)
Чем больше я узнаю о Linux, тем меньше я ненавижу Б.Г.
Ну, вообще то, я никогда не испытывал к нему столь сильных чувств, просто начинаю лучше понимать, за что фирма, производящая Окна, берет деньги. И становится яснее, почему потребители предпочитают платить Биллу (тут, конечно, есть варианты, ну Вы поняли), вместо того, чтобы воспользоваться бесплатной («то есть даром») альтернативой. Но начнем по порядку, и рассмотрим два эпизода взаимодействия с Л.
В последнее время на разрабатываемых мною устройствах функционирует Л (в той или иной своей ипостаси, ну да Вы поняли …), в рамках которой исполняется ПО специального назначения. И вот в процессе взаимодействия с внешними устройствами (специализированными клавиатурами) были обнаружены интересные артефакты поведения ОС, которые и привели к мысли изложенной в эпиграфе.
Эпизод первый — в процессе коррекции программы клавиатуры, подключаемой по USB, «случайно, не-нарочно» был внесен дефект, который приводил к невыдаче строкового дескриптора устройства. Для тех, кто не сильно связан с USB, необходимое пояснение — строковый дескриптор — это необязательная часть описания устройства, которая предназначена исключительно для визуализации типа устройства и производителя системными утилитами. Тем не менее, это не оправдание программистам и такие ошибки не следует допускать, но все бывает в жизни. Как может отреагировать хост под управлением вменяемой ОС в случае подключения к нему подобного неправильного устройства?
Лично я вижу 3 возможные стратегии:
- проигнорировать ошибку и работать с устройством дальше, тем более, что никаких препятствий для этого нет — так поступают Окна, по крайней мере, начиная с 7, и это замечательное решение;
- пометить устройство, как неисправное, выдать соответствующее системное сообщение и дальше игнорировать данное устройство — тоже вполне нормальная и осмысленная реакция;
- повторять запрос строкового дескриптора и, пока он не будет получен, не начинать работу собственно с данным устройством — тоже вполне приемлемое решение, хотя несколько хуже предыдущих, поскольку занимает определенную часть ресурсов процессора и шины USB (а они совсем не безграничны).
Пнп: Следует отметить, что стандарт на интерфейс лишь предусматривает необходимость (рисунок 8.31 на странице 222) при ожидании входного сообщения контролировать время и обрабатывать тайм-аут, как одну из возможных ошибок — повторить запрос 3 раза, а далее выдать сигнал о неудаче транзакции. Дальнейшие действия хоста определяются реализацией. Ну, по крайней мере, я не нашел в стандарте подобной информации, хотя это и не окончательно.
Так вот, разработчики Л не ограничились лежащими на поверхности решениями и пошли глубже, придумав необычайно интересный и, не побоимся этого слова,
4. повторять запрос определенное количество раз, по исчерпанию какового пометить устройство, как неисправное и далее его отключить.
Пока ничего криминального, если бы не одна маленькая деталь («а все остальное — нюансы») — пока Л хост повторяет вышеуказанный запрос, он монополизирует доступ по шине (скорее всего не запускается тайм-аут в железе либо не обрабатывается прерывание от него) и все (!!!) остальные USB устройства простаивают. Занимает этот процесс порядка десятка секунд, в течении которых все устройства недоступны – уже неплохо. А вот и вишенка на торте — после исчерпания попыток провести чтение строкового дескриптора у неправильной клавиатуры, к ней вообще перестают приходить пакеты, она после тайм-аута в 2 секунды понимает, «что что-то пошло не так», и пытается предъявить себя хосту заново путем пере-подключения, в результате чего процесс повторяется. Результаты вполне понятны — работа с шиной просто невозможна, если Вы не готовы к использованию режима «икания». Необычайно оригинальное решение, но это (оригинальность) его единственное достоинство.
Мои знакомые Линуксоиды после демонстрации данного явления сначала пытались объяснить его в стиле «это не баг, это фича такая» (вернее, сначала они, как у них принято, предложили пересобрать ядро с последними патчами, это вообще в Л сообществе универсальный ответ на любое сообщение о возможной ошибке), а потом сказали, что, да, поведение неправильное, но, наверное, где-нибудь в конфигах сборки есть флажок, сбросив или установив который, можно данное поведение системы отключить. Если это действительно так, то единственное название для флажка, которое я могу предложить, это (на русском языке): «Я_действительно_хочу_чтобы_ОС_вела_себя_при_сбое_строкового_дескриптора_как_истеричка», в стиле «Пока эта сука не скажет мне свое имя, я вообще ни с кем разговаривать не буду», прошу прощения за мой французский. Ну и даже если это так и такой флаг есть, разве по умолчанию ОС не должна собираться в нормальном, не извращенном, режиме? Почему-то Окна именно так и делают. Конечно, следовало бы посмотреть исходный текст хоста Л (скорее всего, конкретного USB драйвера) и определить, есть ли такой флажок и как вообще добиваются подобного поведения системы, но по причинам, указанным ниже, это сделано не было, так что ограничимся только констатацией факта.
Вторая фича (намного больше похожая на ошибку, поскольку все-таки в первом случае устройство было неправильное, что я сразу подчеркнул) была выявлена после того, как ошибка программы устройства была устранена и мы начали работать дальше.
Дело в том, что на спроектированном устройстве наличествовали два контроллера, которые реализовывали функцию джойстика и клавиатуры каждый, при этом один обрабатывал левую часть клавиатуры, а второй — правую. Но одна кнопка передней панели была заведена на оба контроллера, поскольку на ней была маркировка «ОГОНЬ» и результаты сбоя одного контроллера были бы весьма неприятны. При нажатии на эту кнопку оба контроллера выдавали символ «пробел» и все было неплохо, пока мы не заметили, что иногда (~10% случаев) после отпускания кнопки Л продолжает считать ее нажатой и приложение переходит в режим непрерывного огня. При этом повторное нажатие и опускание кнопки возвращало систему в нормальный режим.
Было высказано предположение, что близко расположенные (по времени) события от клавиатуры могут быть пропущены, в данном случае сообщение об отпускании кнопки.
Далее были проведены различные действия для определения причины неисправности, но их описание выходит по объему и тематике за данный пост и будет (я надеюсь) описано отдельно. Но сам по себе процесс выяснения причин столь несложной (на первый взгляд) ошибки потребовал таких усилий, что пропало всякое желание разбираться в причине первого описанного в посте бага.
Возвращаясь к эпиграфу, должен сказать, что на Окнах7 данный дефект не наблюдался на протяжении по меньшей мере 100 нажатий, что говорит об устойчивости этой ОС по данному фактору. Опять-таки, исходных кодов я не видел, но поведение программы говорит само за себя.
Маловероятно, чтобы квалификация разработчиков Окон существенно превосходила аналогичный показатель для сообщества с открытым кодом и вопрос, видимо, только в качестве тестирования, которое однозначно проводится в большем объеме (и с более высоким качеством), когда оным занимаются люди, получающие за свою работу деньги (помимо морального удовлетворения).
Вынужден констатировать, что поведение Л, по крайней мере в описанных ситуациях, как нельзя лучше определяется фразой «ну работает же», что нельзя считать приемлемым для ОС, претендующей на надежность и широкое распространение, вот почему мое отношение к Б.Г. в результате данного эпизода улучшилось, поскольку он точно не виноват в происходящем (хотя тут могут быть разные мнения).