Как бы вы решили такую проблему совместимости? перевод

Поскольку статья была написана еще в 2006 году, до выпуска Windows Vista, Реймонд, конечно, уже дал ответ. Так что, для чистоты эксперимента, не спойлите пожалуйста в комментариях.

Привет всем, у вас есть шанс решить одну настоящую проблему совместимости. Ответа еще нет: я жду, как вы будете ее решать. Это реальный баг в трекере Widnows Vista.


Итак, бета тестер сообщил, что Windows Explorer не может показать более чем сто файлов из сетевых папок, расположенных на серверах определённого производителя. Ответственные команды изучили проблему, и выяснили, что сервер неправильно обрабатывает некоторые типы запросов. Несмотря на то, что сервер заявлял, что он поддерживает и «быстрые» и «медленные» запросы, на «быстрый» запрос он возвращал только первые 100 файлов из каталога, и потом выдавал странный код ошибки. С другой стороны, если Explorer переключался в «медленный» режим, все работало хорошо. («Быстрые» запросы появились только в Windows Vista, Windows XP поддерживал только «медленные»). Дополнительная информация: апдейт к серверному ПО, исправляющий эту ошибку, был уже выпущен, однако вендор продолжал поставлять старую версию драйвера.

Что вы бы сделали в такой ситуации? Вот некоторые варианты, выберете свой или предложите новый.

Ничего не делать


Не обращать внимание на неправильную работу стороннего драйвера. Люди, кому не повезло купить подобное устройство, будут получать неполный список файлов. Опубликовать KB, объясняющее проблему, и направлять пользователей к вендору за обновленным драйвером.

Плюсы
  • Операционная система остается «чистой», без всяких хаков совместимости.

Минусы
  • Пользователи с такой проблемой могут даже не понять, что она существует. Даже если пользователь что-то заметит, вряд ли он знает, как искать в KB по имени вендора (или даже дистрибьютора) чтобы посмотреть, есть ли с ним какие-то проблемы. И даже если пользователь сможет найти KB, ему придется обращается напрямую к производителю, минуя дистрибьютора, что может нарушить его гарантию.
  • Если файловый сервер работает, как NAS, пользователь, скорее всего даже не знает, что работает внутри запечатанной пластиковой коробки. Для апгрейда нужно будет ждать, пока вендор выпустит новую прошивку, а до тех пор пользователю придется терпеть потерю данных.
  • Если сервер не находится под контролем пользователя, то ему придется просить администратора про апгрейд драйвера, и надеяться, что администратор на это пойдет.
  • Так как Windows XP не использует «быстрые» запросы и не имеет этой проблемы, пользователи будут считать это багом в Windows Vista.


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


Explorer должен распознать этот странный код ошибки, и показать диалог, который скажет «Сервер \\servername похоже, работает со старой версией драйвера XYZ, которая неправильно работает с каталогами с большим количеством файлов. Не все файлы показаны здесь. Обратитесь к администратору \\servername для апгрейда драйвера». И галочка «Не показывать сообщение снова».

Плюсы
  • Пользователю будет сообщено о неполном результате

Минусы
  • Пользователь ничего не сможет сделать с этим неполным результатом. Это будет похоже на «Ха ха, ты проиграл!»
  • Пользователи часто не знают, кто администратор сервера, и пожелание обратиться к администратору обычно вызывает реакцию – “Ух, а кто это?”, или даже “Это же я! И я абсолютно не понимаю, что это сообщение значит”. (Вспоминаем про домашний NAS)
  • Администратор может иметь свои причины не апгрейдить драйвер на сервере (например, потому что это нарушает гарантию), и вряд ли будет доволен тем, что пользователи постоянно сообщают ему содержание нового диалога.
  • И, так как Windows XP не поддерживает «быстрые» запросы, пользователи будут это считать багом в Windows Vista.


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



Explorer должен распознать этот странный код ошибки, и сказать «Ок, этот сервер имеет ошибочный драйвер. Уже поздно что либо делать, но в следующий раз, я буду использовать медленный запрос для доступа к серверу».
Чтобы исключить возможность DOS атаки, надо запоминать только, скажем, 16 последних серверов (если список будет неограничен, атакующий может переполнить всю память, создав сервер, который отвечает миллионом различных имен с этим кодом ошибки).

Плюсы:
  • Windows автоматически определяет проблему и решает ее.

Минусы
  • Первый список файлов с сервера все равно будет неправильным.
  • Если вы регулярно посещаете 16 (скажем) серверов, когда вы посетите 17, первый уйдет из кэша, и в следующий раз вернет опять неправильный список.
  • Можно также разработать механизм, который позволит сетевому администратору определять список «плохих» серверов.
  • И так как Windows XP не поддерживает быстрые запросы, пользователи будут это считать багом в Windows Vista.


Сделать настройку в сетевом клиенте, которая включает «медленный» режим.



Добавить настройку в сетевом клиенте «Если кто то спрашивает, поддерживает ли сервер быстрые запросы, всегда говорить, Нет, даже если сервер сказал Да». В этом случае, никакая из программ не будет пробовать использовать «быстрый» режим, все будут использовать только медленный. Но, по крайней мере, это будет работать.

Плюсы
  • Если эта настройка включена, пользователь никогда не получит неправильные данные

Минусы
  • Так как определение не автоматическое, проблемы те же, что и в первом случае «Не делать ничего». Пользователи должны знать, что у них проблема и знать, что искать, чтобы найти эту настройку в KB. До этого, подведение будет выглядеть так, как будто это баг в Windows Vista.
  • Сервера, которые работают нормально, будут тоже работать в медленном режиме, несмотря на то, что правильно поддерживают «быстрые» запросы.


Сделать настройку в Explorer, которая включает «медленный» режим



Сделать настройку в Explorer, которая говорит «Всегда используй медленный режим, никогда не используй быстрые запросы». Запросы будут идти медленнее, но всегда будут работать. Но, это повлияет только на работу Explorer; другие программы, которые спросят «Поддерживает ли сервер быстрые запросы?», получат соответствующий ответ, и при попытке использовать «быстрые» запросы, получат все те же проблемы, что уже решил Explorer.

Плюсы
  • Если эта настройка включена, пользователь никогда не получит неправильные данные

Минусы
  • Плюс к тому, что указано в предыдущем пункте, каждая программа будет иметь собственную настройку для такого поведения.



Отключить быстрый режим по умолчанию



Перестать поддерживать быстрый режим в сетевом клиенте, так как он ненадежен; некоторые сервера не поддерживают его правильно. Это заставит все программы использовать медленный режим. Однако, оставить возможность включить его обратно.

Плюсы:
  • Все просто работает.

Минусы:
  • «Быстрый режим» можно было вообще не разрабатывать. Он отключен по умолчанию, и почти никто не озаботится тем, чтобы включить его, потому что все и так работает
  • Люди будут обвинять Microsoft в нечестной игре, так как клиенты работают в «медленном режиме», несмотря на то, что сервера поддерживают «быстрый». И, конечно, продукты Microsoft будут уступать конкурентам, которые поддерживают быстрый режим безо всяких ограничений.


Будьте креативны. Если приводите свое решение, составьте также список плюсов и минусов.

Еще один очевидный вариант, не описанный Реймондом в статье, но отвеченный в комментариях.

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

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

А также отвечаю сразу на комментарий типа «Майкрософту надо открывать и полностью документировать свои протоколы, сами виноваты». Баг, о котором пишет Реймонд, никакого отношения к правильному исполнению протокола не имеет.
+27
20 ноября 2010, 15:31
8
awhiler 7,9

комментарии (53)

+2
shakalaka #
Интересная статья. Итог охватывает любую сферу айти.
Но мне вот интересно, какой из вариантов был выбран по-дефолту все же?
+4
SabMakc #
При первом чтении, если вернулась ошибка, сразу перечитать список и вернуть полный, а дальше обращаться с сервером, как с медленным.
Как вариация: прочитать, встретить ошибку.
Перейти в медленный режим, прочитать «пропустив» первые 100 записей и продолжить возвращать правильные результаты.

+ «прозрачно» для пользователя.

— Пользователь о проблеме не узнает.
Решение: предупредить об этом пользователя, что соединение принудительно в медленный режим переводится, запомнить эту информацию для данного сеанса.
— Данные могут поменяться.
Решение: надо отдельно запоминать 100 записей и возвращать «не их».
0
awhiler #
Хорошо.

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

Если же подобный алгоритм вставлять внутри сетевого клиента (прозрачно для остальных программ) см. мой комментарий в конеце статьи.
0
SabMakc #
Да, модификация сетевого клиента.
Не подходит, потому что: сетевой клиент возвращает список не по завершению запроса, а частями, асинхронно, во время выполнения. Так что первая часть списка может быть возвращена (и использована программой-клиентом) еще до того, как сетевой клиент получит ошибку и поймет, что надо перечитать список.
Этот?
Поэтому мы при переходе в медленный режим возвращаем не все, а только то, что не вернулось в 1м чтении.
Итог — для программы все прозрачно, она и не знает что были проблемы, для нее это просто задержка.
0
awhiler #
окей, как вариант, принимается, хотя я думаю там слишком много тонкостей всплывет при реализации (например — недетерминированный порядок сортировки при выдаче файлов, то есть второй запрос вернет файлы в совсем другой первой сотней).

И опять же, стоит ради одного бага так усложнять основной код?
0
SabMakc #
Согласен, вариант сложный в реализации и напоминает скорее заплатку, а не стройное и красивое решение.
И стоит ли? Это скорее зависит от конкретной ситуации: наличие свободного времени и политики компании по отношению к подобным вещам.
+1
babay88 #
эм… а это уже проблема другой программы.
вот правда.
0
Guria #
Ответы ещё не читал:
Реализовать этот очевидный вариант в Эксплорере, а для сторонних разработчиком описать вариант подобной реализации в KB
–6
tzlom #
Еще один очевидный вариант, не описанный Реймондом в статье, но отвеченный в комментариях.

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

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

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

а вообще труЪ способ решения — вариант настройки «только медленное соединение», база с настройками соединений, при обнаружении проблемы писать «ОЛО сервер УГ, почитайте наше КОВ где всё написанно, если хотите работать в медленном режиме нажмите [кнопку]»

труЪ linux way — по факту обнаружения бага написать 100500 гневных статей из серии «стандарты для идиотов, да?» и разместить где попало
производитель зафиксит бажину чтобы его не поливали дерьмом на форумах (опять таки никто в здравом уме не будет рекомендовать глючное железо) и к выходу вислы всё уже будет работать (WIN)

P.S.
я честно говоря не знаю как чувачки из редмонда(и индии) решили эту проблему, но учитывая сердечно любимый список кернел хаков для поддержки откровенно кривого, но популярного софта думаю что был выбран самый тупой вариант (в конце концов M$ и правильный подход к ПО вещи несовместимые)
0
awhiler #
баг в самбе был исправлен и закрыт до того, как его обнаружили в мсфт. проблема в том, что патч сложно доставить на все устройства, где его нет. на некоторые устройства его вообще нельзя доставить (прошивка не upgradable)
+15
apangin #
Креативный вариант: встретив данный код ошибки, выдавать клиенту дополнительный псевдоэлемент (каталог) типа «Show all files...»
Зайдя в него, пользователь будет получать полный список, т.к. система, встретив в пути этот псевдокаталог, его уберет и будет использовать медленный запрос.

Дополнительно можно воспользоваться 3-м способом (запоминать сервер и использовать в следующий раз другой тип запроса).
–1
gopline #
Собственно, вот он — правильный ответ.
НЛО прилетело и опубликовало эту надпись здесь
0
phasma #
При обнаружении ошибки делать допольнительные запросы с offset.
+1
Antelle #
Я бы сделал настройку где-нибудь глубоко в реестре — «использовать медленный режим».
И, если получен такой-то код ошибки, показать сообщение со ссылкой на KB. В KB рассказать, что лучше всего, если вы можете это сделать, проапгрейдить драйвер, потому что запросы будут бегать быстрее. Но если этого сделать нельзя, то вот есть такая настройка в реестре, можете временно включить её (продолжая пинать админа).
0
kashey #
А я всетаки не понял где проблема.
Читаем блоками, отстукивая о выполнении очередного блока програме.
Полили ошибку, и хотим переиницилизироваться в медленном режиме, как писали выше, да не можем сбросить сиквенс.

Какие проблемы — врубиться в быстром режиме, запомнить 100 файлов что получается получиться, врубиться в медленном режиме, начать читать данные исключая файлы их блок листа(топ 100). Отрепортить клиента о новом блоке.

Если порядок четко соблюдается можно и не запоминать «топ 100», а просто отмотать ответ медленного варианта сразу до нужной позиции…
0
apangin #
Блоков нет. Перемотки тоже нет. Есть API вида FindFirstFile/FindNextFile. В какой-то момент FindNext возвращает ошибку.
Запоминать файлы — не вариант, потому что придется запоминать уйму лишних данных на уровне драйвера на каждый запрос, а это очень накладно. Не запоминать — тоже не вариант, потому что альтернативный способ не обязан возвращать файлы в том же порядке, да и содержимое каталога может запросто измениться.
0
kashey #
запоминать не уйму, а 100 записей, и можно не в драйвере а в юзерспейсе. И только если мы находимся в режиме востановления.
Перемотка == FindNextFile_inner без отстука.

Никак проблем нет. Даже если у вас сетевая карта уйдет в перегруз и на удаленном диске головка попадет на бэдблок — конечный автомат на пару стейтов и 4 ивента это пережует.
0
apangin #
Ну, если мы говорим о фиксе в Explorer — тогда, конечно, просто. Если же о фиксе имплементации SMB в Vista, то все это драйвер, по идее, должен делать. Объем запоминаемых данных навскидку порядка 128 * sizeof(_WIN32_FIND_DATAW) ~= 74K, немало. И надо запоминать каждый раз, мы ж не знаем наперед, встретим ли ошибку.
Или вы предлагаете перечитывать в случае ошибки сначала быстрым способом, потом медленным? Хм. Во-первых, это может быть слишком долго. А, во-вторых, ненадежно. Например, сначала мы прочитали файлы с 1 по 127. На 128 получили ошибку. Перечитываем быстрым способом, получаем файлы 1, 3-128 (2й в это время удален), пропускаем их. Перечитываем медленным способом, выдаем пользователю файлы 129-500. 128-й теряется.
0
kashey #
посему храним 128 * sizeof( _WIN32_HASH_ ) от этого самого FIND_DATAW
Да — именно это порождает проблему разряда просмотра ДВД с Белоснежкой. Но для случаев рескана директории отработает замечательно.
И да, я имел и виду что мы сваливаемся в медленный режим именно когда валимся.
Тоесть работали в быстром, упали, переключились в медленный и отработали востановление сиквенсов, продолжили в медленном.
0
seriyPS #
Кстати да, хранить не _WIN32_FIND_DATAW а hash(_WIN32_FIND_DATAW)
+1
PingWin #
Это всё хорошо, а если формат возвращаемых данных немного различается? Ну, допустим, в новом варианте дополнительно присутствуют пара свежих атрибутов? Или информация о файловых потоках (http://msdn.microsoft.com/en-us/library/aa364404(VS.85).aspx)?

Я не знаток SMB, просто предположение :)
0
kashey #
В данном случае из контекса следует что имея одну точку входа(на поиск) мы умеем в ней отрабатывать оба варианта запроса в любом случае.
–19
LastHorseradish #
>Как бы вы решили такую проблему совместимости?
перестал пользоваться виндами.
–11
amarao #
Прислать патч разработчику неправильного сервера, если разработчик сервера откажется его принять, принять патч в основные дистрибутивы.

Oh, shi..., это же проприентарное ПО. Извините, извините. Еитесь сами.
+6
LexL #
Сказали же, что баг уже был пофикшен.
Просто куча железа уже продана с багом в firmware, кто должен всё это патчить?
+8
awhiler #
samba — проприентарное ПО?

Вы бы читали бы что то дальше первой строчки.
+6
asis #
Ты попутал, с самим патчем как раз проблем нет, проблема в то что есть устройства которые фиг пропатчишь, чисто технически.
–1
LexL #
1) Если есть возможность определить версию сервака. Перед запросом опрашивать эту версию, и если версия багнутая, использовать медленный вариант запросов. Информацию о багнутости/не багнутости сервера кешировать ограниченным кешем на месяц в черном списке.

2) Использовать быстрый вариант, при получении ошибки, перечитать медленным способом до последнего полученного быстрым вариантом элемента, далее отдавать клиенту.

3) Гибридный вариант 1 и 2. Регистрировать багнутость сервера в черном списке :)
0
adontz #
А это не про Remote Differential Compression?
0
medin #
Ну так не честно. Я хочу знать ответ (зря статью прочитал чтоли?!), но я не специалист чтобы решать задачку :/
0
medin #
А нельзя сначало медленно и убедившись, что ошибки нет второй раз заходить быстро и занести в белый список *сказал делитант*
0
awhiler #
ответ будет, конечно же, но потом:)
0
grokinn #
параллельно посылаем быстрый и медленный запросы если ошибки нет игнорируем результаты меленного если ошибка возникает скрываем ее, отображаем первые сто файлов и используем результаты второго запроса для отображения остальных

минус — костыли это те ещё.
0
Guria #
минус — реализовать можно только в приложении, но не в драйвере
0
Qiwichupa #
все же мне кажется это проблема вендора и он должен ее решать новой прошивкой, коль уж есть обновление драйвера. Пользователи будут негодовать, конечно, но строго говоря вендор заслуживает тонн ненависти, если он не протестировал железку перед выпуском и тем более если сделал невозможным перепрошивку.
0
asis #
Логично, но в реальности то пользователи будут обвинять Майкрософт во всех грехах и именно им приходится делать костыли.
0
Qiwichupa #
да не, в любом случае шишки на вендора. Если это домашний NAS — будет возврат по гарантии, если корпоративная закупка — разговор еще короче )
+1
seriyPS #
«А почему мой NAS работал в XP, а когда я поставил висту — перестал? Виста-отстой!»
0
asis #
Именно так. И фиг докажешь кому что проблема в NAS а не у MS.
0
Qiwichupa #
Я даже не вижу смысла МС что-то доказывать. То что сотня хомячков поднимет вой не разобравшись — погоды не сделает, а впендюривать в свой код костыли, правящие чужие фейлы — верх маразма.
0
asis #
Делает это погоду, еще как делает. MS зарабатывает деньги на продаже софта, и если вдруг выяснится что чего то там не поддерживается просто многие не купят.
0
squint #
В топку «быстрые запросы» )
0
squint #
ну вот — я оказался прав
0
dab512 #
Читаем в быстром.
Встретили ошибку — переключились в медленный режим
Записали название сервера и работаем с ним в медленном режиме
Раз в минуту/час/день пробуем работать в быстром. Если работает — удаляем из списка.
Для серверов из списка включаем медленный режим.
Список известных серверов можно обновлять через интернет.
0
cnupm #
1. Поломать протокол — быстрый режим будем включать только на серверах, поддерживающих новый протокол. Минус — соснули пользователи не кривых nas со старым протоколом, корректно отрабатывающих быстрые запросы, выпуск кривых драйверов для сервера — и всё ломается.
2. База совместимости — всегда работаем с сервером в режиме медленных запросов, если он отсутствует в базе. Минус — очередной выпуск кривых драйверов для сервера — и капут.
3. API. Добавляем новый вызов апи(или флаг) — по умолчанию FindFile обращается по старому протоколу, если указан спец. флаг(или дёрнули FindFileEx) — ищем по быстрому методу. Плюс — старые приложения не ломаются, насрать на кривые сервера, минус — кривые дрова на сервере(апдейт) — и каюк, плюс старые приложения не получат новые возможности.
+3
muromec #
стоп-стоп-стоп… ms прогибается под баги самбы? ох нифига себе.
+2
Stalker_RED #
мс традиционно прогибается под все баги популярных устройств.
временами имеет от этого кучу проблем и потоки ненависти от адвансед юзеров, потому что прячет ошибки, а юзеры негодуют, наблюдая эту мистическую автомагию, и моляться на бубны.
с другой стороны, мс имеет н-ное количество счастливых домохозяек, которые даже не догадываются насколько китайский и кривой у них NAS.
0
kmeaw #
Всегда работать в медленном режиме. После завершения вызова попробовать сделать быстрый запрос. Если он успешный, то предложить пользователю использовать быстрые вызовы для этого сервера в следующий раз. Если быстрый вызов завершился с ошибкой, то уведомить пользователя.
+1
amirul #
То же самое, но пользователю ничего не предлагать. Просто вести белый список и перепроверять сервера в фоне, по дефолту начиная общаться с «незнакомцами» в медленном режиме.
0
Guria #
Минус — быстрое вытеснение хороших серверов из небесконечного белого списка. В итоге пользователь опять думает, что в Висте баг.
0
stas_agarkov #
правильный варинт тот, который указали ему в комментариях
но не нужно выдавать данные пользователю пока не получили статуса ошибки или пока не удостоверились, что правильно получили от сервера полный список
есть только один минус: первый раз список будет получаться дольше, чем остальных разов, но этим минусом можно пренебречь
0
side2k #
Интересный подход к решению проблемы.
Выглядит так: на одном из этажей подъезда (без лифта) жители заваливают площадку хламом, пройти невозможно. Варианты решения проблемы:
1. Ничего не делать
2. Повесить табличку с предупреждением перед входом на эту клетку.
3. Повесить табличку и нанять таджика для уборки.
4. Под потолком этой клетки подвесить перекладины, чтоб проходить клетку на руках. Пройти смогут только адвансед юзеры.
5. Просто нанять таджика, но скидываться на него придется даже тем, кто живет ниже злополучной клетки.

Неудивительно, что в итоге из ПО получается непонятная смесь, подпертая костылями со всех сторон. Зато для домохозяек — «работает», ага.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.