Чудеса невиданной кривизны

У меня дома в качестве домашнего сервера используется небольшой неттоп на платформе Nvidia ION (чипсет Nvidia MCP79 + процессор Intel Atom), к которому по eSATA подключён большой внешний жёсткий диск. По сути это временное решение до покупки какого-нибудь NAS, но пока оно меня устраивает — в неттопе есть гигабитный Ethernet (в реальных условиях скорость передачи данных составляет 40-60 мегабайтов в секунду), плюс он практически не шумит, а netatalk 3 позволяет использовать его как полноценный файл-сервер для Мака с поддержкой Time Machine.

После перестройки домашней сети я столкнулся с тем, что неттоп при загрузке перестал получать настройки сети по DHCP. При этом если после загрузки я руками вводил в консоли команды «sudo ifdown eth0» и «sudo ifup eth0», то сеть спокойно поднималась. Роутер при этом показывал, что линк устанавливается на скорости 1 Гбит/с и с полным дуплексом. Я проявил чудеса изобретательности и прозвонил тот сегмент, к которому подключался неттоп, мультиметром. Итог: все жилы целые, перепутанных пар тоже нет. Самое удивительное, что при подключении к роутеру напрямую коротким патчкордом (а не через розетку в стене) неттоп нормально получал параметры сети по DHCP. Все остальные устройства в сети отлично работали, будучи воткнутыми в ту же самую розетку, в которую втыкался неттоп.

Путём экспериментов я установил следующее:

  • даже при прямом подключении неттопа к роутеру при загрузке линк поднимался только в том случае, если я использовал короткий патчкорд. При использовании длинного патчкорда (5 м) неттоп отказывался получать параметры сети по DHCP при загрузке;
  • несмотря на то, что и роутер, и неттоп умеют автоматически определять MDI/MDI-X, при подключении кросс-кабелем любой длины линк при загрузке не поднимался;
  • если перед загрузкой Linux на неттопе я загружался с флешки в другую операционную систему, при последующей загрузке Linux линк нормально поднимался;
  • если линк не поднялся во время загрузки, он нормально поднимался при вытыкании и последующем втыкании сетевого кабеля.

Изучение вывода команды dmesg показало, что во время загрузки модуль forcedeth (драйвер Ethernet-контроллера Nvidia) несколько раз пытается завести сетевую карту и отваливается с загадочным сообщением «link is not ready». Где-то ближе к концу загрузки ОС драйвер выдавал сообщение «link is now ready», а сразу после этого — «link is down».

Сначала я попытался решить проблему путём написания простенького скрипта, который передёргивал бы интерфейс (ifdown/ifup) во время загрузки. Проблема оказалась в том, что если положить скрипт в /etc/init.d/, то особых средств для контроля за временем его исполнения нет. А чтобы передёргивание помогло, его надо было производить уже после того, как драйвер рапортовал о готовности линка. Дальнейшие эксперименты показали, что линк гарантированно поднимался, если я в помещал в скрипт команду «sleep 30» (пауза 30 секунд) перед передёргиванием интерфейса, но в сочетании с двухминутным ожиданием получения сетевых параметров при загрузке это приводило к тому, что неттоп грузился очень долго. К тому же в этом случае надо было из скрипта запускать все сетевые сервисы (типа apache, ssh, netatalk), которые во время загрузки не стартовали из-за отсутствия линка.

Поиск в интернете показал, что эта проблема очень характерна для Ethernet-контроллеров Nvidia под Linux. А решение пришло с неожиданной стороны: оказывается, производитель неттопа выпустил специальную версию BIOS для использования с операционной системой Linux. После прошивки этого BIOS'а (как я на Маке создавал загрузочную флешку с FreeDOS — это отдельная история) в меню BIOS Setup появился новый пункт с названием Ethernet ROM Preload или как-то так. После его включения Ethernet-контроллер начал нормально инициализироваться при загрузке…

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

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

Плюсануть
Поделиться
Показать комментарии