Debian на DNS-327L: инструкция по приготовлению

Если Вы иногда почитываете этот унылый инженерный бложек, то помните мое приключение с DNS-327L и творчестве криворуких инженегров длинка C тех самых пор я еще немного причесал сию поделку китайцев, а именно:

  • Кнопка питания теперь заведена в dts куда надо, как и остальные кнопки
  • Апстрим ядра 3.18 и 3.19 работают и не зависают
  • Вся годнота от Марвелла, а именно DMA engine, mv_xor, watchdog и mv_cesa включены и работают
  • Я таки выдавил из себя небольшую (на пять простых пунктов) инструкцию как запустить на нем debian
  • Сделал замеры потребления

БАЛШОЕ ЖЫРНОЕ ПАРЕДУПРЕЖДЕНИЕ: Я не несу никакой ответственности за все то, что Вы сделаете со своим девайсом начитавшись этой статьи. Все нижеперечисленное при выполнении так же лишит Вас гарантии.

IMG_20150215_141546

Ладно, теперь составим список того, что нам потребуется для нашего блюда:

  • Отвертка крестовая
  • Переходник с USB на UART, 3.3 вольта, 2.54 IDC штыри, провода (Ну или HC-05/HC-06 модули, как вариант.)
  • Паяльник (Только не надо брать советский пыточный инструмент 70х годов на 200 ватт. Нежнее надо быть!) и навыки пайки
  • Парочка жестких дисков для нашего NAS’а
  • Хост-компьютер с debian или ubuntu
  • Желание быстро и решительно потерять гарантию
  • Свободное время

Шаг 1: впаиваем уарт, получаем доступ к u-boot

Сначала отклеиваем резиновые ножки (и не теряем!), вывинчиваем четыре винта под ними. Аккуратно снимаем крышку (осторожно — провод от вентилятора). Нам нужны 4 пятака на плате, на которые выведен UART. Параметры: 115200 8n1. Напряжение лог. «1»: 3.3V. Распиновка:

[RXD|(gap)|3.3v|GND|TXD]

IMG_20141018_160141

IMG_20141018_164702

Греем паяльник, впаиваем штыри. Как альтернативу, можно взять HC-05/HC-06 модуль, сконфигурить вклеить двусторонним скотчем и распаять на соплях. HC-05 модули нынче стоят дешево, но зато удобства добавляют много.

Как только последовательный порт подцеплен — включаем железку, и начинаем давить сначала «1», потом пробел. Этот танец с бубном прерывает загрузку и вываливает нас в командную строчку загрузчика.

Шаг два: ядро и u-boot

TL;DR: Берем исходники тут

Так как убут у нас не поддерживает deviceTree, dtb придется прилеплять к образу ядра. т.е. CONFIG_ARM_APPENDED_DTB=y

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

export CROSS_COMPILE=arm-module-linux-gnueabi-
uimage() {
    cp zImage-precious arch/arm/boot/zImage
    cat arch/arm/boot/dts/${1}.dtb >> arch/arm/boot/zImage
    ARCH=arm LOADADDR=${2} make uImage
    cp arch/arm/boot/uImage ./uImage-${3}
    cp arch/arm/boot/uImage /srv/tftp/uImage-${3}
}
 
 
rm -f arch/arm/boot/zImage
ARCH=arm make menuconfig zImage dtbs -j8
cp arch/arm/boot/zImage ./zImage-precious
uimage armada-370-dlink-dns327l 0x00008000 altmera

Есть два способа подсунуть ядро NAS’у. Первый — по tftp, второй — залить в NAND. Второй более опасен, так как если затереть загрузчик — нас ждет долгий квест по раскирпичке нашей железки. Согласно документации у Armada 370 есть какая-то магия в ROM загрузчике, которая позволяет безболезненно раскирпичить железку. Но я ее не проверят. Потому лучше до этого не доводить.

Вариант с TFTP

Итак, грузиться по tftp проще всего. NAND мы при этом не трогаем, да и обновляться таким образом крайне просто — только заменить ядро на tftp сервере и все дела. Потому все, что от нас тут требуется — поднять tftp сервер, скопировать образ ядра туда и выполнить вот такую магию в командной строке загрузчика (заменяем на свои ip адреса по вкусу).

setenv ipaddr 192.168.0.5
setenv serverip 192.168.0.1
setenv 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;'
setenv bootargs console=ttyS0,115200n8 root=/dev/md0 rootfstype=ext4
setenv bootcmd 'run voodoo; tftp;bootm;'
saveenv

Обратите внимание на переменную ‘voodoo’. DLink-человеки настраивают RGMII phy и напряжения на нем… скриптом в юзерспейсе, когда сеть уже поднялась. Так как это требует еще и костыльного драйвера ядра, то на апстрим ядрах работать не будет. Именно поэтому я это переместил в загрузчик. См. предыдущий пост про этот NAS за разъяснением.

Теперь загружаться можно просто введя:

run bootcmd

или дождавшись когда истечет таймаут.
Вариант с NAND

TFTP нам и для этого потребуется, так что сервер придется поднимать и часть которая написана выше прочитать. Для начала немного теории. NAND у длинка содержит две копии ядра. Первая используется для обычной загрузки, вторая для случаев если bootcmd профейлился, например если нажать CTRL+C во время tftp. Может еще и при какой комбинации кнопок — я не проверял. Так как размер нанда/офсеты могут отличаться на другом NAS’е я привожу тут описание того, как определить правильные офсеты.
Let’s start with how the stock firmware boots. Для начала смотрим на стоковую команду bootcmd.

Вот так она выглядит на моем NAS’е:

nand read.e 0xa00000 0x500000 0x400000;nand read.e 0xf00000 0xa00000 0x300000;bootm 0xa00000 0xf00000

Давайте расшифруем эту магию. Синтаксис nand read выглядит примерно так:

nand read [physical_address_where_to_load] [offset_of_nand_in_bytes] [number_of_bytes_to_read]

Т.е. сначала читаем ядро с адреса 0x500000 в NAND в адрес 0xa00000 в RAM. Потом initrd из 0xa00000 в NAND в адрес 0xf00000 в RAM. Потом их запускаем.

Из этого нам нужен только один адрес: 0x500000 в NAND. Туда мы закинем ядро, на initrd забьем.

Теперь надо узнать NAND офсет второй копии ядра. Если мы прервем по CTRL+C run bootcmd, то увидим текст вроде такого:

NAND read: device 0 offset 0x5d00800, size 0x500000

Попался! Так что второе (аварийное) ядро лежит в 0x5d00800 и должно быть меньше 5 мегабайт (0x500000). Все это захардкожено и окружением не меняется. Длинк такой длинк.

Отсюда следует. Для замены основного образа ядра в NAND делаем так:

tftp 0xa00000 uImage-altmera

nand erase 0x500000 0x500000

nand write ${fileaddr} 0x500000 0x500000

Настраиваем окружение и добавляем черную магию:

setenv 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;'
setenv bootargs console=ttyS0,115200n8 root=/dev/md0 rootfstype=ext4
setenv bootcmd 'run voodoo; read.e 0xa00000 0x500000 0x400000; bootm 0xa00000' 
saveenv

если хотим поменять фейлсейф ядро — процедура выглядит так же. Единственное но — адрес 0x5d00800 не выровнен по границе erase блока. Потому делать придется так:

tftp 0xa00000 uImage-altmera
nand erase 0x5d00000 0x500000
nand write ${fileaddr} 0x5d00800 0x500000

Вуоля!

Шаг три: Готовим жесткие диски (RAID зеркало)

Корневая фс, простоты ради будет на жестком диске и грузиться мы будем с root=/dev/md0. SWAP я тоже отзеркалил, т.к. это позволит вытыкать жесткие диски на горячую без выключения питания. Если RAID будет не зеркало, а что-то другое, то процедура будет немного отличаться.

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

  1. Чтобы загрузиться с /dev/md0 нам нужен RAID-автодетект на уровне ядра. А это будет работать только с метаданными версии 0.90
  2. Ядро автодетектит RAID-массивы, но не сканирует /dev/md0 на предмет разделов. т.е. root=/dev/md0p1 работать не будет

 

Отмечая вышесказанное разбиваем жесткий диск. Для начала меньшего объема. Я оставил 10GiB для корневой файловой системы, 2GiB на подкачку, остальное под файлопомойку которую смонтирую в /srv/. Для разбивки можно использовать все, что только есть в мире. Я пользую по старинке cfdisk. Не забываем тип раздела ставить в 0xfd, т.е. «Linux RAID autodetect», желательно и размеры выровнять кратно 4 килобайтам.

Теперь можно скопировать таблицу разделов sfdisk’ом на второй диск

sfdisk -d /dev/sda | sfdisk /dev/sdb

Теперь можно создавать массивы. Если подключать оба жестких диска лень/только один шнурок — можно сделать вырожденный массив, а потом уже «на месте» добавить второй и синхронизировать.

Вот так это делается для двух дисков:

mdadm --metadata=0.90 --create /dev/md0 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1

mdadm --metadata=0.90 --create /dev/md1 --level=1 --raid-devices=2 /dev/sda2 /dev/sdb2

mdadm --metadata=0.90 --create /dev/md2 --level=1 --raid-devices=2 /dev/sda3 /dev/sdb3

А вот так мы делаем вырожденный массив:

mdadm --metadata=0.90 --create /dev/md0 --level=1 --raid-devices=2 /dev/sda1 missing

mdadm --metadata=0.90 --create /dev/md1 --level=1 --raid-devices=2 /dev/sda2 missing

mdadm --metadata=0.90 --create /dev/md2 --level=1 --raid-devices=2 /dev/sda3 missing

 

Создаем файловые системы:

mkfs.ext4 -L root /dev/md0

mkswap -f /dev/md1

mkfs.ext4 -L data /dev/md2

Шаг четыре: Бутстрепим дебиан

Особо тут рассказывать нечего, так как бутстреп дебиана отдельная тема для целой серии постов. Для этого нам потребуется debian/ubuntu на хост-компьютере, debootstrap/multistrap и qemu-arm-static.

Ниже следующее можно использовать как референс, но лучше заглянуть в официальную документаци. Там написано больше и понятнее. Нижеследующее выполняем от root’а:

debootstrap --foreign --variant=minbase --arch=armel wheezy debian-wheezy http://ftp.ru.debian.org/debian/
cp `which qemu-arm-static` ./debian-wheezy/usr/bin/
cp /etc/resolv.conf ./etc/resolv.conf
echo "/debootstrap/debootstrap --second-stage" | chroot .

Прочихавшись, это нам выплюнет готовую корневую фс. Далее нам потребуется адекватный sources.list. Оный можно сгенерить онлайн тут
и скопипастить содержимое в etc/apt/sources.list.

Далее нам надо будет чрутнуться в нашу корневую фс и доставить пакеты. Вот мой минимальный джентльменский набор.

apt-get install wget curl ifupdown isc-dhcp-client openssh-server net-tools nano apt-utils inetutils-ping dialog mdadm smartmontools watchdog

Не отходя от кассы можно накатить и ajenti и mysql. Перед тем, как скопировать корневую фс на жесткий диск не помешает так вы же выставить через ‘passwd’ пароль root и включить getty на последовательном порту.
Последнее легко делается добавлением вот этой строчки в etc/inittab нашей корневой фс.

T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100

Наконец, надо сделать /etc/fstab более или мене адекватный. Вот мой:

/dev/md2  /srv/ ext4 noatime,journal_async_commit    0   0
/dev/md1  swap  swap defaults 0  0

tmpfs   /lib/init/rw    tmpfs   size=16K,rw,nosuid,relatime,mode=0755 0 0
tmpfs   /var/run        tmpfs   size=1M,rw,nosuid,mode=0755     0 0
tmpfs   /var/lock       tmpfs   size=512K,rw,noexec,nosuid,nodev,mode=1777 0 0
tmpfs   /var/tmp        tmpfs   size=512K,rw,noexec,nosuid,nodev,mode=1777 0 0

Для копирования фс я обычно пользуюсь tar’ом. Строчку данную привожу из головы, потому перед использованием надо осмыслить и убедиться что я нигде не ошибся.

cd rootfs
sudo tar cpf - . --exclude=./sys --exclude=./dev --exclude=./proc| sudo tar vxpf - -C /media/nas_hdd_mount_point

После создаем директории, которые мы исключили: /proc /sys /dev /mnt и /srv на целевом диске. Вот и все! Размонтируем наш диск, втыкаем его в NAS.

Шаг пять: Грузимся, настраиваем систему

Если все прошло хорошо, можно то NAS должен загрузиться и предложить залогиниться по UART’у (или ssh если мы успели корректно настроить сеть). Логинимся под root’ом и настраиваем систему. Теперь это обычный линуксовый сервак уровня VPS за 5 баксов. Разве что места под данные тут сильно больше.

Шаг шесть: свистелки энд перделки

Я нарисовал мелкий скрипт, который запускается по cron’у и смотрит на появление reallocted секторов на диске. Как только такие появляются — он зажигает красный диод напротив профейлившего жесткого диска. Его можно закинуть /etc/cron.hourly:

#!/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 > /sys/class/leds/$2/trigger
                echo "Yikes! Drive $DISK has $REALLOC reallocs!"
        else
                echo none > /sys/class/leds/$2/trigger
        fi
}
 
check_drive 1 dns327l:amber:sata-l
check_drive 2 dns327l:amber:sata-r

Управление вентилятором. За нас тут уже все сделали, потому берем и собираем dns320l-daemon и кидаем на нашу файловую систему. Вот мой /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  = 25
TempHigh = 34
Hysteresis = 2

Ему так же нужен init скрипт, который я и нарисовал не долго думая:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          dns320ldaemon
# 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
 
# 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
 
:

Так же лучше установить и настроить watchdog и wd_keepalive, чтобы заюзать аппаратный /dev/watchdog который у нас есть в системе. Кстати, стоковая фирмваря его не юзает, отчего если и вешается — то ребутать приходится руками

Бонус #1

Я держу на NAS mysqld. Производительности хватает, чтобы ворочался в том числе и этот блог. Вот мой my.cnf. Пришлось пару неделек пособирать статистку, позапускать mysqltuner. Я выбрал myisam, так как в отличие от innodb ему требуется меньше памяти.

[mysqld]

user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
basedir         = /usr
datadir         = /srv/mysql.altmera/
tmpdir          = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
skip-name-resolve
default-storage-engine=myisam

key_buffer_size = 32M
max_allowed_packet = 4M

table_open_cache = 512
sort_buffer_size = 128K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 64K

query_cache_type = 1
query_cache_size = 32M
query_cache_limit = 8K

thread_stack            = 256K
thread_cache_size       = 4

tmp_table_size      = 16M
max_heap_table_size = 16M

 
# For low memory, InnoDB should not be used so keep skip-innodb uncommented unless required
skip-innodb
 
     # Uncomment the following if you are using InnoDB tables
     #innodb_data_home_dir = /var/lib/mysql/
     #innodb_data_file_path = ibdata1:10M:autoextend
     #innodb_log_group_home_dir = /var/lib/mysql/
     #innodb_log_arch_dir = /var/lib/mysql/
     # You can set .._buffer_pool_size up to 50 - 80 %
     # of RAM but beware of setting memory usage too high
     #innodb_buffer_pool_size = 16M
     #innodb_additional_mem_pool_size = 2M
     # Set .._log_file_size to 25 % of buffer pool size
     #innodb_log_file_size = 5M
     #innodb_log_buffer_size = 8M
     #innodb_flush_log_at_trx_commit = 1
     #innodb_lock_wait_timeout = 50
 
     [mysqldump]
     quick
     max_allowed_packet = 16M
 
     [mysql]
     no-auto-rehash
     # Remove the next comment character if you are not familiar with SQL
     #safe-updates
 
     [isamchk]
     key_buffer = 8M
     sort_buffer_size = 8M
 
     [myisamchk]
     key_buffer = 8M
     sort_buffer_size = 8M
 
     [mysqlhotcopy]
     interactive-timeout

Вот выхлоп mysqltuner.pl натравленный на него:

root@altmera:~# perl mysqltuner.pl 

 >>  MySQLTuner 1.4.0 - Major Hayden <major@mhtx.net>
 >>  Bug reports, feature requests, and downloads at http://mysqltuner.com/
 >>  Run with '--help' for additional options and output filtering
[OK] Logged in using credentials from debian maintenance account.
[OK] Currently running supported MySQL version 5.5.40-0+wheezy1
[OK] Operating on 32-bit architecture with less than 2GB RAM

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED -InnoDB +MRG_MYISAM 
[--] Data in MyISAM tables: 73M (Tables: 269)
[--] Data in PERFORMANCE_SCHEMA tables: 0B (Tables: 17)
[--] Data in MEMORY tables: 0B (Tables: 1)
[!!] Total fragmented tables: 6

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 10d 11h 1m 29s (2M q [2.402 qps], 36K conn, TX: 5B, RX: 508M)
[--] Reads / Writes: 75% / 25%
[--] Total buffers: 80.0M global + 1.0M per thread (151 max threads)
[OK] Maximum possible memory usage: 231.0M (46% of installed RAM)
[OK] Slow queries: 0% (0/2M)
[OK] Highest usage of available connections: 26% (40/151)
[OK] Key buffer size / total MyISAM indexes: 32.0M/11.9M
[OK] Key buffer hit rate: 99.9% (7M cached / 4K reads)
[OK] Query cache efficiency: 67.0% (1M cached / 1M selects)
[OK] Query cache prunes per day: 0
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 37K sorts)
[!!] Temporary tables created on disk: 48% (64K on disk / 131K total)
[OK] Thread cache hit rate: 99% (244 created / 36K connections)
[OK] Table cache hit rate: 25% (368 open / 1K opened)
[OK] Open file limit used: 54% (642/1K)
[OK] Table locks acquired immediately: 99% (827K immediate / 827K locks)

-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    Enable the slow query log to troubleshoot bad queries
    When making adjustments, make tmp_table_size/max_heap_table_size equal
    Reduce your SELECT DISTINCT queries without LIMIT clauses
Variables to adjust:
    tmp_table_size (> 16M)
    max_heap_table_size (> 16M)

Бонус #2
Замеры потребления

DNS-327L _очень_ мало жрет. С 12V источником питания и 2 жесткими дисками (1TiB WD Black + 1TiB WD Green) он кушает порядка 1.15 Ампер в простое (13.8 Ватт) (С максимальной скоростью вентилятора). 1.28 Ампер на 100% загрузке CPU (dd if=/dev/urandom of=/dev/null), 1.4 Ампера при дисковой нагрузке (dd if=/dev/md0 of=/dev/null). 1.38Amps с двумя вышеупомянутыми тестами в параллель. Это выливается в 16.8 Ватт потребления под нагрузкой, что является безусловно успехом.

Потребление жестких дисков дает основной вклад в эти числа, как легко догадаться.
IMG_20150215_141546
 

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