«Ошибки в ДНК» или как неправильный дизайн может приводить к миллионным убыткам

:

Написать эту заметку меня побудили очередная статья с «криком души»: ну почему Windows в очередной раз требует перезагрузки при изменении чего-либо (обычно это установка/удаление программ, но бывают и другие случаи)? Почему разработчики Windows-приложений — такие лохи, а разработчики Linux-программ (где таких сообщений при установке «обычных программ» не бывает) — такие молодцы?

Этот феномен всем давно известен — но задумывались ли вы о том откуда у него «ноги растут» и почему в других операционных системах (Linux, MacOS X и т.п.) подобные окна являются чем-то исключительным, а в Windows — постоянным?

Нет, виноваты не только «криворукие писатели софта» — основная вина лежит на компании Microsoft. Все эти бесконечные запросы — сочетание ошибки в дизайне MS DOS, совершённой более 20 лет назад и теории разбитых окон. Это было горячее время для Microsoft — она тогда не была монстром, подобным сегодняшнему, не могла совершать ошибок и годами разрабатывать нечто от чего всех бы воротило, а потом выпускать следующую версию OS, которая бы исправляла ошибки предыдущей (Windows98 => Windows98SE, Windows Vista => Windows 7, etc). Потому когда потребовалось что-то сделать с поддержкой локальных сетей и противопоставить тогдашнему лидеру (это была компания Novell со своей сетевой операционкой Netware) хоть что-нибудь разумное, то долго думать о дизайне не приходилось — было сделано то, что было сделать проще всего и что почти наверняка бы работало без ошибок и нареканий. В MS-DOS появилась утилита SHARE.EXE, позволявшая использовать несколько программ одновременно (вначале — только на разных компьютерах, так как MS DOS оставалась однозадачной, позднее — на одном, после того, как Windows получила распространение) и в ней была совершена та самая ошибка, последствия которой мы и расхлёбываем до сих пор. Причём всего ужаса совершённой тогда ошибки никто не заметил ибо ничего ужасного, на первый взгляд, в ней не было.

В чём же состояла ошибка? В том, что сказав A Microsoft не сказал B. Когда Microsoft копировал из Unix их основную фишку — иерархическую файловую систему (можете ли вы поверить что первая версия MS DOS даже этой возможности не содержала?) для упрощения он не скопировал оттуда одну важную идею: разделение понятия «файл» и «имя файла». В Unix — эти понятия разделены. Есть файл (или, вернее, inode) и есть его имя (запись в каталоге). Права доступа к inode и права доступа к имени файла никак, вообще говоря, не связаны между собой (на самом деле потом пришлось-таки ввести парочку ограничений, но это другая история). Главное: если программа открыла файл и даже если она сделала это в эксклюзивном режиме — на права доступа к записи в каталоге это не распространяется. Что это значит? Это, в частности, значит, что вы можете любой файл «удалить» (на самом деле если этот файл используется — например это файл подкачки — то он не будет удалён до тех пор пока он будет использоваться) и создать «на его месте» новый (на самом деле новый файл будет создан, скорее всего, в другом месте — но вот запись в каталоге будет размещена там же). В MS DOS же программа SHARE.EXE (и все её потомки включая ядра таких OS как Windows Vista и Windows 7) действуют не так. Если доступ к файлу заблокирован, то заблокирован и доступ к его имени! В MS-DOS (с файловой системой FAT, позволявшей каждому файлу иметь только одно имя) это выглядело логично, в NTFS — это выглядит уже странно (вы можете дать файлу новое имя, но не можете удалить старое), но сделать с этим ничего нельзя так как множество программ полагается на это (решение было принято, напоминаю, более 20 лет назад).

Каковы последствия этой ошибки? Последствия — самые серъёзные. Многие файлы в Windows вообще не могут быть мофицированы во всемя её работы (так как используются системой) и потому было предложено несколько механизмов позволяющих эту проблему обойти. Можно указывать имя файла (скажем драйвера) в реестре и создавать при обновлении новый файл/каталог — а старый удалять, скажем, при перезагрузке (или в другое «удобное время») — это подход применяется, в частности, в .NET. Можно просто заменять файлы после перезагрузки — но тут не всё просто ибо нужна специальная «заплатка» в OS, позволяющая это делать (и она есть в Windows), но главное — «обновлённый» файл, ждущий своей очереди не виден на своём привычном месте и неясно каким он будет — и потому много программ инсталляции обнаружив что очередь «заказов на изменение конфигурации после перезагрузки» непуста просто форсируют оную перезагрузку. В общем — много чего можно делать и делается, но при всём при этом установка любой программы может потребовать перезагрузки (если разработчики предусмотрели это), либо (что IMNSHO хуже) установка перезагрузки не потребует, но и программа работать не будет. Веселее всего бывает когда установленная программа работает до перезагрузки, а потом — ломается. Так бывает когда одна программа заказала некое изменение «на после перезагрузки», инсталлятор другое программы поставил вторую программу без учёта этих изменений (он же их не видит — они же в очереди! а форсировать перезагрузку вторая программа не решилась чтобы не нервировать пользователя!), а после перезагрузки — система сломалась. Ну и окончательную точку ставит «теория разбитых окон»: если решение части проблем — только перезагрузка системы и никак иначе, то почему бы не потребовать оной перезагрузки и в других случаях когда это прсто упростит жизнь разработчикам?

В Unix (и, соответственно, в Linux и/или MacOS) ситуация совсем иная: любой файл всегда можно заменить на «улучшенную версию» (если у вас хватит на это прав), так что при установке большинства программ перезагрузка не требуется никогда — разумеется это заставляет разработчиков пытаться избежать её и в других случаях…

К сожалению в последнее время и в Linux начали «снижать планку»: поробуйте перейти с KDE 3.x на KDE 4.x без остановки системы или хотя бы без перезагрузки X'ов! Это не так-то просто и требует массы костылей… Но в любом случае такие ситуации случаются в Linux/MacOS/etc гораздо реже чем в Windows. Потому что у Windows — «ошибка в ДНК», доставшаяся ей от прародителя — MS DOS.

Чему нас учит эта история? Тому что ошибки дизайна бывают разные: некоторые можно потом легко исправить, а некоторые — будет вас преследовать десятилетия… Осталось только научиться их различать…