Dlink DNS-327L: Как НЕ надо делать NAS

В двух словах: Запустил Debian на DNS-327L со свежим ядром с kernel.org, моя ветка ядра на github‘е. Внутри родной прошивки треш, ад и содомия.

Сильно подробнее и в красках:

Если вы заметили, то последние недели мой унылый инженерный бложик то косячил-косячил, а последнюю неделю с лишним вообще лежал отдавая честный 500.

Но, обо всем по порядку. Рассказ в этот раз будет долгий, ибо и приключение выдалось… Долгое. Начались проблемы с того, что накрылся жесткий диск в RAID-1 зеркале. Причем из двух жестких дисков: ветеран и новичок накрылся сравнительно новый сигейт, а WDшка серверная как работала, так и работает. Да, в гуано скатился сигейт. WDшка хоть и сильно горячее была, но жива.

Держать данные на вырожденном массиве как-то некомильфо, да и материночка на которой у меня был построен NAS держалась на ладан, тормозила. В общем напрашивался апгрейд.

Руки в ноги, поехал и прикупил я обнову. Жесткий диск на замену, да модную коробочку NAS — Dlink DNS-327L, с прицелом на OpenWRT/Debian. Помятуя о том, какие длинк ребята, блок питания 12в 3А я сразу отложил — запитал от своего… Жить я решил на стоковой прошивке, ибо пока не хотелось терять гарантию…

Yep, I found use for that free sticker HaD sent me!
Да, я нашел куда налепить тот халявный стикер, что мне прислали с hackaday!

Тут-то и начались приключения. В общем, сначала, он захотел сам переформатить диск. Готовое зеркало он почему-то не подхватил. Окей, придется делать маневр данными. Ну, думаю, создам сейчас вырожденный raid-1 массив из одного диска, скопирую данные, потом воткну второй, синхронизирую… профит!

Благо, mdadm —create /dev/md0 -l raid1 -f -n 1 /dev/sda1 сделать просто. Фиг вам!

Оно не дает создать вырожденный массив из одного веника. Только из двух. Воткнуть в PC и создать там? Но я не знаю в каком виде этот NAS хочет его отформатировать. На тот момент я даже не знал, mdadm там используется или нет.

Почесав голову, решил сделать тупо: воткнул почти_что_умерший сигейт, просыпавший релокейтами в пару с новым WD, отформатировал их. Оказалось, эта хрень создает GPT таблицу разделов, на ней создает несколько томов, откусывая под свои нужды несколько гигабайт, а потом на одном из них уже создает запрошенный RAID1 через mdadm. Секрет был в GPT таблице разделов и служебных разделах. На всякий случай разберу подробнее что и как:

Таблица разделов диска, после того, как по ней прошлась прошивка Dlink’овского NAS’а выглядит так.
537 мегабайт оно откусывает от каждого диска на подкачку, еще гигабайт форматирует в ext4, зеркалирует и оставляет пустым (НАФИГА???), еще гиг просто оставляет неотформатированным разделом, который ничем не монтируется. Содержимое мне проверять было лень. Все, что после этих зверств осталось — это наше зеркало. На листинке ниже разделы 4 и 2 зеркалируются средствами mdadm.

Model: ATA ST31000528AS (scsi)
Disk /dev/sdc: 1000GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system     Name                Flags
 1      1049kB  538MB   537MB   linux-swap(v1)  Linux swap
 4      538MB   1612MB  1074MB  ext4            Linux/Windows data
 2      1612MB  999GB   998GB   ext4            Linux/Windows data
 3      999GB   1000GB  1074MB                  Linux/Windows data

Даже по гигабитной сети данные по NFS копировались долго. Больше 700 гиг, причем дофига мелких файлов. Заняло это часов эдак 18.

Довольный, вытаскиваю убитый сигейт, втыкаю на его место старичка WD, с которого все это копировалось и запускаю перестройку. Через два часа оно меня обрадовало, что перестройка завершена. Однако массив так и остался degraded, и оно настойчиво предлагало мне повторить операцию.

На третий раз Шаман Зоркий Глаз понял, что это косяк в прошивке. Очередной. Про периодически съезжающие таблички, вырвиглазный дизайн, подвисания скриптов, тормоза и рекомендацию использовать IE я молчу, привык уже. Быстрый взгляд выявил, что внутри используется глобальный и надежный PHP + mysql прикрученные к lighttpd. Сразу бросаются в глаза процессы php-fcgi в списке процессов и торчащий портом наружу mysql (спасибо, nmap подсказал). Данные о происходящих операциях оно в жабоскрипт получает ajax’ом… В виде XML! JSON? Не, не слышали. Все это составляет очень странное впечатление. Отдельные вопросы вызывает скорость работы. На 1.2 Ghz ARM оно шевелится медленнее, чем аналогичное на МВ77.07 на 324Mhz ARM1176!

Ах да, и еще если старт/стоп службы, о котором он кидает POST запрос занимает слишком долго — lighttpd падает. Совсем. До ребута.

Ладно, раз косяк в прошивке, значит надо обновиться. На железке 1.0, а на сайте 1.3 и мой баг в списке. Выкачиваю свежую прошивку с сайта dlink, заливаю…

413 — request entity too large.

Тут уже утро, пора на работу. Пробрасываю порт наружу, с работы решил попробовать еще раз, как выдалась минутка. При заливке удаленно с небольшой скоростью издалека — оно прошивку скушало! Почему/как? Остается без ответа.

Перестраиваю рейд, теперь оно ожило. Вечером настраиваю шары, попутно проклиная криворуких людей, писавших фирмварю, перезагружаю железку и…

После перезагрузки меня радует информация о том, что он собрался авто-ребилдить массив. Опять. На этот раз проблема оказалась в джампере «Enable 1.5Gbps phy» на одном из веников. При нем веник инициализируется немного дольше, и это (моя догадка) вызывает в скриптах дибилинка рейс, который заставляет его перестроить массив. После снятия джампера и перестройки массива все заработало. Но пока я это понял — два раза перестроить массив таки пришлось.

Глюки тем временем продолжались, lighttpd после обновления прошивки стал падать на каждый чих. Быстро сообразил, что проблема в настройках. Сразу видно миграцию конфигурации из одной фирмвари в другую они не осилили толком. Сбрасываюсь на за заводские настройки — о чудо, половина косяков ушла, тормозить стало меньше!

Подключаю NFS шары, настраиваю… И тут замечаю, что что-то не то с правами. А именно — на все стоит 777. Чиню… В какой-то момент опять 777. Методом проб и ошибок выясняется, что чудные ребята из dlink делают chmod -Rf 777 /mnt/ при !каждой! перезагрузке. А если подцепить к нему USB флешку или жесткий диск в чем-то отличном от fat или ntfs — получаем chmod -R 777 в подарок на все файлы. Причем не только на этой модели. Взял с полки баночку, натер лицо фейспальмовым маслом…

facepalm

В этот момент у меня возникла серьезная дилемма. Сдать это дерьмо по гарантии, или доработать напильником. А к слову сказать, железка внутри весьма любопытная. Marvell Armada 370 (armv7 + VFP, без неона) @ 1.2Ghz, 512MB DDR3, 128Mb NAND. USB3.0, 2xSATA, и прочие радости. И судя по всему есть поддержка в OpenWRT, да и в апстрим ядре. Вопросы разрешил короткий диалог с exception13:

ncrmnt: вот думаю, менять или открыть и вкостылить дебилиан или OpenWRT
exception13: второе же
exception13: странный вопрос от тебя =]
ncrmnt: знаешь, эксепшн... бывают моменты когда я сомневаюсь в своем красноглазии. Когда проскакивают мысли а не забить ли мне на это и не найти ли себе тупую тян с неплохими формами... Спасибо что в такие моменты ты мне напоминаешь кто я... *пошел за отверткой*

В общем, в задницу эту гарантию. Начал я с того, что разобрал эту хрень и заглянуть в ее нутро, фотки прикладываю.

Сама борда, вид сверху. Виден сам SoC, Marvell 88F6707, 512 MiB DDR3, 128MiB NAND, гигабитный ethernet PHY, на PCIe сидит xHCI (USB3.0) контроллер. Встроенный в чип — только USB2.0, и он не выведен. На питании саты эффективные менеджеры нам недопаяли конденсаторов. Жлобы! Но вроде бы работает. И на том спасибо.

IMG_20141018_160029

К SoC цепляется через /dev/ttyS1 мелкий микроконтроллер от Weltrend. Он питается от батарейки, играет роль RTC, рулит питанием, WoL, и еще много чем.

IMG_20141018_160102

IMG_20141018_160128

На обратной стороне можно узреть два незапаянных места под DDR3 память. Теоретический максимум на этой борде — 1Gb, но нам приходится обходится 512ю. Допаивать я бы не рискнул, ибо слишком большая вероятность что с другой стороны платы все поотваливается.

IMG_20141018_160141

Гарантийных пломб тут нигде нет, так что если не срывать винты, паять аккуратно и отмывать канифоль спиртом — всегда можно прошить родную прошивку и притвориться блондинкой. Начал я с UART’а, взял как обычно HC-05, настроил на 115200 8n1.

IMG_20141018_160302

После того, как я при помощи двусторонней липкой ленты и тоненьких проводков впаял внутрь все это хозяйство я увидел убут. Чтобы попасть в командную строчку — надо остервенело давить «1» и «пробел» до того, как истечет таймаут.

IMG_20141018_164702

В убуте есть tftp, usb и много еще чего. Но usb у нас работать не будет, так как поддерживает только встроенный в чип EHCI, который никак по плате не выведен. Печально. На плате напаяно 128Mb NAND, на которых и живет прошивка.
Загрузив сток, я по уарту смог залогинится с паролем администратора, и снять дамп файловой системы на USB флешку для последующей экзекуции. По исходникам я прошелся по диагонали, а значит в ходе этого код ревью много треша и угара мог попросту упустить. Но даже того, что я нашел хватит на то, чтобы схватится за голову и произнести несколько ласковых матерных слов в адрес авторов этого… нечта:

1. Загрузка списка пользователей. unlink() в документации на PHP наверное не нашли…

<?php
if (!empty($_FILES)) {
 //echo $_FILES['file']['tmp_name'];
 system("rm -f /tmp/import_users");
 move_uploaded_file($_FILES['fileToUpload']['tmp_name'],"/tmp/import_users");
}
?>

2. В конце этого скрипта кроется ответ на вопрос «а почему все тормозит?». Вот так настоящие джедаи сражаются с race condition’ами в javascript’е.

<?php
//if(!isset($_REQUEST['name'])) throw new Exception('Name required');
//if(!preg_match('/^[-a-z0-9_][-a-z0-9_.]*$/i', $_REQUEST['name'])) throw new Exception('Name error');
//
//if(!isset($_REQUEST['index'])) throw new Exception('Index required');
//if(!preg_match('/^[0-9]+$/', $_REQUEST['index'])) throw new Exception('Index error');
//
//if(!isset($_FILES['file'])) throw new Exception('Upload required');
//if($_FILES['file']['error'] != 0) throw new Exception('Upload error');
 
//201308 Sean Add for upload security (Consumer Storage Security Vurnubility)
$ip = gethostbyaddr($_SERVER['SERVER_ADDR']);
$result = @stripslashes( @join( @file( "http://".$ip."/cgi-bin/nas_sharing.cgi?cmd=71&uuid=".$_SERVER['REMOTE_ADDR']),"" ));
$equal = strcmp($result, "success");
if ($equal != 0)
{
        header("HTTP/1.1 302 Found");
        exit();
}
//201308 Sean Add for upload security (Consumer Storage Security Vurnubility)
 
 
$path = str_replace('//','/',$_REQUEST['folder']);
$filename = str_replace('\\','',$_REQUEST['name']);
$target =  $path . $filename . '-' . $_REQUEST['index'];
 
//$target =  $_REQUEST['folder'] . $_REQUEST['name'] . '-' . $_REQUEST['index'];
 
move_uploaded_file($_FILES['file']['tmp_name'], $target);
 
 
//$handle = fopen("/tmp/debug.txt", "w+");
//fwrite($handle, $_FILES['file']['tmp_name']); 
//fwrite($handle, "\n"); 
//fwrite($handle, $target); 
//fclose($handle); 
 
// Might execute too quickly.
sleep(1);
 
?>

И такого треша, угара и содомии там выше крыши. Но оставим разбор полетов профессионалам веб дизайна.

Начал я с того, что собрал самое свежее ядро с kernel.org, а имеено 3.17.1 и при помощи метода высоконаучного тыка нашел куда заведены диоды, питание SATA, USB3.0 и прочее. В итоге я выдавил из себя dts файлик, который можно найти у меня на github’е в ветке dlink-dns327l. mvebu_defconfig вполне подходит для начала.

Далее, нам надо определиться откуда брать корневую фс. Так как NAND памяти у нас кот наплакал — 128MiB, на самом RAID массиве корень как-то не сильно хотелось держать (чревато возней с initramfs, да и хотелось как-то разделить данные и корень), то под корневую ФС я решил пожертвовать USB 3.0 портом куда воткнул старую флешку. Туда я закинул полученную при помощи debootstrap корневую фс Debian Wheezy.

Обращаю внимание, что под эту железку — (armv7 + vfpv3 БЕЗ НЕОНА) нам сгодится либо debian armel, либо raspbian. Debian armhf работать из-за отсутствия неона не будет.

После начальной тривиальной настройки, первое что необходимо было сделать — управлять вентилятором. По счастью начинка weltrend’овского мк не менялась со времен DNS-320L, а значит можно использовать [url=http://www.aboehler.at/hg/dns320l-daemon]dns320l-daemon[/url]. Единственное что отличается — карта температуры. По ходу для моего он отдает немного заниженную температуру (либо датчик стоит с края платы), потому в конфигурационном файле для dns320l-daemon я это значение немного компенсировал, чтобы ядро выше ~65 градусов не грелось. Мой /etc/dns320l-daemon.ini:

[Serial]
Port = /dev/ttyS1
NumberOfRetries = 3
 
[Daemon]
ServerPort = 57367
ServerAddr = 127.0.0.1
SyncTimeOnStartup = 0
SyncTimeOnShutdown = 0
 
[GPIO]
SysfsGpioDir = /sys/class/gpio
PollTime = 100
 
[Fan]
PollTime = 10
TempLow  = 30
TempHigh = 36
Hysteresis = 2

К нему я нарисовал вот такой init скрипт:

### BEGIN INIT INFO
# Provides:          dns320l-daemon
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: DNS320L daemon
# Description:       Fan and rtc daemon
#                    
### END INIT INFO
 
# Author: Andrew 'Necromant' Andrianov <spam [at] ncrmnt [dot] org>
#
# Do NOT "set -e"
 
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="NAS Fan and RTC daemon"
NAME=dns320l-daemon
DAEMON=/usr/sbin/$NAME
DAEMON_ARGS=""
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
 
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
 
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
 
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
 
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
 
 
dns_cmd()
{
{ echo "${*}"; sleep 1; } |  telnet localhost 57367
}
 
#
# Function that starts the daemon/service
#
do_start()
{
        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
                || return 1
        start-stop-daemon --start --quiet --exec $DAEMON -- \
                $DAEMON_ARGS \
                || return 2
        dns_cmd hctosys
 
        # Add code here, if necessary, that waits for the process to be ready
        # to handle requests from services started subsequently which depend
        # on this one.  As a last resort, sleep for some time.
}
 
#
# Function that stops the daemon/service
#
do_stop()
{
        dns_cmd systohc
        killall -9 dns320l-daemon
        return 0
}
 
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
        #
        # If the daemon can reload its configuration without
        # restarting (for example, when it is sent a SIGHUP),
        # then implement that here.
        #
        start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
        return 0
}
 
case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  status)
        status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
        ;;
  #reload|force-reload)
        #
        # If do_reload() is not implemented then leave this commented out
        # and leave 'force-reload' as an alias for 'restart'.
        #
        #log_daemon_msg "Reloading $DESC" "$NAME"
        #do_reload
        #log_end_msg $?
        #;;
  restart|force-reload)
        #
        # If the "reload" option is implemented then remove the
        # 'force-reload' alias
        #
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
          0|1)
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
          *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  *)
        #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
        echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
        exit 3
        ;;
esac

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

#!/bin/bash
 
# A more or less hacky way to get drives in the manner they are PHYSICALLY wired
# in the system. We can't use /dev/sdX names, because they may swap in respect to
# which initializes first. Numbering starts with '1'
 
get_drive()
{
        DRIVE=`find /sys/|grep ata${1}|grep events_async|cut -d"/" -f 12`
        echo "/dev/$DRIVE"
}
 
check_drive()
{
        DISK=`get_drive $1`
        REALLOC=`smartctl -A $DISK|grep Reallocated_Sector_Ct | awk '{print $10}'`
        if [ "$REALLOC" != "0" ]; then
                echo default-on &gt; /sys/class/leds/$2/trigger
                echo "Yikes! Drive $DISK has $REALLOC reallocs!"
        else
                echo "Drive $DISK is operational"
                echo none &gt; /sys/class/leds/$2/trigger
        fi
}
 
check_drive 1 dns327l:amber:sata-l
check_drive 2 dns327l:amber:sata-r

Этот скрипт мы закидываем спокойно в /etc/cron.hourly и если у нас на жестком диске появляется хотя бы один релокейт — мы об этом узнаем по красному светодиоду.
Хотя подробные письма от smartd на почту никто не отменял.

В виде веб интерфейса я остановился на ajenti, как самом вменяемом решении. Да и дизайн веб интерфейса не выглядит у него так же жутко, как у дефолтного поделия длинковцев.

9

И все вроде бы работало… До того самого момента, как через 4 часа работы меня произошел жесткий зависон. Под жестким я понимаю то, что в консоль не было отправлено ни единого сообщения. Сколько-то времени я долбался с этим, не буду описывать все проклятия, которые я отправлял авторам этой железки. Просто просуммирую все то, что узнал.

Первая засада крылось в скрипте инициализации железа, который нашелся в стоковой прошивке. Называется этот скрипт hardware_init.sh, который привожу ниже.

#!/bin/sh
 
echo "hardware init"
 
# enable usb power
mem_rw -w -t 1 -o 0x18100 -v 0x2010
 
#for SPI clock
mem_rw -w -t 1 -o 0x1100c -v 0xfb
 
#/* hardware request phy */
mem_rw -w -t 1 -o 0x184e0 -v 0xa8a
 
mem_rw -w -t 2 -o 22 -v 0x2
mem_rw -w -t 2 -o 25 -v 0x77
mem_rw -w -t 2 -o 24 -v 0x5747
mem_rw -w -t 2 -o 22 -v 0
 
# modify for hw sata eye
mem_rw -w -t 1 -o 0xA2834 -v 0xc92a
mem_rw -w -t 1 -o 0xA283c -v 0xaa2b
 
mem_rw -w -t 1 -o 0xA4834 -v 0xc92a
mem_rw -w -t 1 -o 0xA483c -v 0xaa2b

Сумрачные гении из Dlink родили свою реализацию /dev/mem «с преференсом и поэтессами» под названием /dev/REG, через которую работает их утилита mem_rw. Первая строчка включает питание на USB путем записи в регистры GPIO, минуя подсистему ядра. Пять баллов за решение! Хотя, с другой стороны… Если бы они все это в ядро запихали, фига с два я бы понял откуда ветерок дует.

Следующая строчка задает cкорость i2c. Не знаю почему в комментарии они написали SPI. Лучше мне и не знать. Наверное.

Последние 4 строчки тоже понятны — лезем в регистры мультиплекса GPIO, и вешаем на 2 светодиода режим «активность SATA».

А вот то, что идет между ними — это очень сильное колдунство, смысл которого до меня стал доходить после романтического вечера со strace и оbjdump и вдумчивого чтения того небольшого количества документации, которое есть по marvell в открытом доступе. И именно оно снижает частоту зависания системы. Ниже привожу их с уже моими комментариями:

# Пишем в регистры IO config, задаем напряжения на RGMII на 1.8 вольт.
# По умолчанию там 3.3 вольта. 
mem_rw -w -t 1 -o 0x184e0 -v 0xa8a
 
# Нижеследующее пишется в регистры ethernet PHY. 
# Выбираем страницу номер 2
mem_rw -w -t 2 -o 22 -v 0x2
 
# ОЧЕНЬ СИЛЬНОЕ КОЛДУНСТВО
mem_rw -w -t 2 -o 25 -v 0x77
mem_rw -w -t 2 -o 24 -v 0x5747
 
# Выбираем страницу 0
mem_rw -w -t 2 -o 22 -v 0

Секрет кроется в тех двух строчках, на которых в открытом доступе документации нет. Запись этого колдунства положительно сказывается на стабильности работы системы.
Мое подозрение — что тут мы говорим PHY что собираемся использовать 1.8 вольт (как? что? Так как документации на PHY у нас нет, мы можем только гадать). Немного поигравшись командами uboot, я нашел способ все это сделать в окружении uboot. Таким образом никакие кровавые скрипты нам не потребуются:

voodoo=mw.l 0xd00184e0 0xa8a; phyWrite 0 16 2; phyWrite 0 19 77; phyWrite 0 18 5747; sleep 1; phyRead 0 19; phyRead 0 18; phyWrite 0 16 0;
bootcmd=run voodoo; nand read.e 0xa00000 0x500000 0x400000; bootm 0xa00000

Это здорово увеличило стабильность работы, но все равно зависания каждые 3-6 часов на апстрим ядре остались. Итого, у нас есть 2 способа запустить дебиан на DNS-327L:

1. С ядром из DLink’овской прошивки:

  • idmapd будет фейлится при старте, будут проблемы с chown’ом на nfs.
  • Нет /sys/class/leds и /sys/class/buttons, про кнопочки и диоды забываем, ага.
  • Нельзя загрузиться с усб флешки: ядро вырубает питание на шине усб при загрузке
  • Не загружается по nfs
  • Нет драйвера вочдога
  • …И едва ли будет обновляться Dlink’ом
  • Выдает бенчмарки hdparm немного более быстрые, нежели апстрим (или это мое воображение?)
  • Нет исходников

2. Апстрим ядро:

  • Зависания каждые несколько часов. Частично решаются использованием аппаратного вочдога (См. мой конфиг внизу). Возможно что-то с питанием, так как на родном блоке питания зависает субъективно реже.
  • Может грузиться с USB
  • Просто обновлять ядро!
  • Есть кнопочки, диодики, все как положено

Вот пожалуй и все пока, осталось несколько проблем, но к ним я думаю вернуться тогда, когда длинки изволят выложить исходный код согласно лицензии GPL (Либо когда будет тоскливо, и нечем заняться)

Оставшиеся загадки:

  • У DNS-320L была линия GPIO от weltrend’а к SoC’у, которая говорила что пользователь нажал и подержал кнопку питания. На DNS-327L ее не нашлось. Оно вообще было?
  • Загадочное i2c устройство по адресу 0x13. Сток использует i2cset/i2cget внутри себя, чтобы работать с ним
  • Зависания! (Главная проблема на данный момент)
  • GPIO линии на RESET и USB BACKUP не подцепляются в devicetree к gpio-keys, вызывая непрерывный probe deferral. Выглядит, как баг в апстрим ядре

Мой watchdog.conf:

#ping                   = 172.31.14.1
#ping                   = 172.26.1.255
#interface              = eth0
#file                   = /var/log/messages
#change                 = 1407

# Uncomment to enable test. Setting one of these values to '0' disables it.
# These values will hopefully never reboot your machine during normal use
# (if your machine is really hung, the loadavg will go much higher than 25)
#max-load-1             = 24
#max-load-5             = 18
#max-load-15            = 12

# Note that this is the number of pages!
# To get the real size, check how large the pagesize is on your machine.
#min-memory             = 1

#repair-binary          = /usr/sbin/repair
#repair-timeout         = 
#test-binary            = 
#test-timeout           = 

watchdog-device = /dev/watchdog
watchdog-timeout = 60
interval = 15

# Defaults compiled into the binary
#temperature-device     =
#max-temperature        = 120

# Defaults compiled into the binary
#admin                  = root
#interval               = 1
#logtick                = 1
#log-dir                = /var/log/watchdog

# This greatly decreases the chance that watchdog won't be scheduled before
# your machine is really loaded
realtime                = yes
priority                = 20

# Check if syslogd is still running by enabling the following line
#pidfile                = /var/run/syslogd.pid   

Dlink DNS-327L: Как НЕ надо делать NAS: 6 комментариев

  1. Вы пишете:
    «Обращаю внимание, что под эту железку — (armv7 + vfpv3 БЕЗ НЕОНА) нам сгодится либо debian armel, либо raspbian. Debian armhf работать из-за отсутствия неона не будет.»

    Позвольте не согласиться: у меня стоит Debian wheezy именно armhf и работает под chroot на ядре из DLink’овской прошивки. Я так понимаю, Debian armhf собирается с минимальными параметрами сопроцессора vfpv3d16, который присутствует в Armada370.

  2. Спасибо за статью подчерпнул много интересного.
    P.S. за статью «Debian на DNS-327L: инструкция по приготовлению» тоже большое спасибо (пишу тут т.к. в той статье нет места для коментариев)

  3. Опаньки, а WDMyCloud Mirror почти один-в-один по железу и, что более, убийственно — ровно теже грабли в прошивке (mem_rw тулза, полное игнорирование /sys/class/* и прочий ужос.)
    Я то думал, это прогеры WD такие ушлые, а это, похоже, прогеры Marvell идиоты… (Наверняка все эти костыли притащились из какогонибудь OpenWRT от девборда.

    В общем — аффтор, нам есть что обсудить. Пиши на мыло — раскажу пару интересных баек, а также подскажу, как кое-что из этого добра пофиксить (А что — сделать правильно).

      1. под mainline kernel 4.7.2 у меня почему то не работает сетевой адаптер (no carrier), хотя по стоком всё ОК, не подскажете куда копать ?

Добавить комментарий