Сказ о Raspberry и внешнем HDD. Первый опыт разработки под платформу
Доброго времени суток, Хабр! Пару недель назад зачесались руки гика —
захотелось мне приобрести довольно нашумевший и всем известный
одноплатный мини-компьютер Raspberry Pi. Модель была выбрана самая
«крутая» — версия «B» с 512Mb ОЗУ на борту. История о покупке и
первичной настройке не подходит к теме этого поста, тем более, что её
можно прочитать вот здесь.
Этот пост о другом. После всех манипуляций с настройкой захотелось
попробовать машинку, так сказать, «в деле». Идея возникла практически
сразу. Дома у меня имеется 3 компьютера, 2 смартфона, бюджетный роутер, и
внешний жёсткий диск на 2Tb — Seagate Expansion External. Интерфейс
подключения у HDD — USB. Роутер из разъёмов имеет только Ethernet и
дырку для шнура электропитания. Все мои устройства соединяются с
роутером только по WiFi, и ни одно не может работать в постоянном
режиме. Но тут появляется Raspberry. Миниатюрные размеры платы позволяют
разместить систему вида
[HDD<=USB=>RPi<=Ethernet=>DIR300NRU(роутер)<=WiFi=>LAN]
прямо на подоконнике и использвать диск в локальной сети, а её мизерное
энергопотребление позволяет держать включенной практически постоянно.
RPi работает под управлением семейства ОС Linux, а именно я на неё
установил Raspbian. Казалось бы, поставить сервер samba и расшарить
диск… но это было бы слишком просто. Конечная задача усложнилась:
необходимо делать внешний диск доступным в локальной сети, только в том
случае, если мой смартфон к этой сети в данный момент подключён, иначе
диск размонтировать, тем самым снижая на него нагрузку и его
энергопотребление. Значит писать будем демон, и писать будем на Python.
Поехали!
Первым делом, первым делом...samba!
Сначала нужно настроить самбу и железо. Цепляем хард к Малине через USB,
Малину к роутеру по Ethernet. Всё включаем в розетку. Коннектимся по
SSH к RPi, я использую PuTTY под Windows в качестве клиента.
В Raspbian «из коробки» нет возможности подключить NTFS-раздел диска для
записи, монтируется он только как Read-Only и не пускает к себе по
локальной сети.
Не беда, сейчас установим нужный драйвер:
pi@raspberrypi ~ $ sudo apt-get install ntfs-3g
Дальше нам нужно знать имя раздела для монтирования, узнаём так:
pi@raspberrypi ~ $ sudo fdisk -l
И получаем примерно такой вывод:
Disk /dev/sda: 2000.4 GB, 2000398931968 bytes
255 heads, 63 sectors/track, 243201 cylinders, total 3907029164 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0006573a
Device Boot Start End Blocks Id System
/dev/sda1 2048 409602047 204800000 83 Linux
/dev/sda2 409602048 419842047 5120000 82 Linux swap / Solaris
/dev/sda3 419842048 3907028991 1743593472 7 HPFS/NTFS/exFAT
Внешний HDD у меня имеет имя sda, раздел обзывается sda3, у вас может быть другое. Запоминаем его.
Дальше смотрим куда монтировать. По умолчанию диск автоматически
монтируется в /media/Имя_тома. Я решил не заморачиваться и оставить его
там. Путь к директории у меня: /media/DataR.
Теперь настраиваем сам сервер samba. Открываем файл конфигурации для записи:
pi@raspberrypi ~ $ sudo nano /etc/samba/smb.conf
Про настройку можно подробно прочитать в сети, я лишь приведу свой файл конфигурации:
[global]
workgroup = WORKGROUP
server string = RPi Fileserver
netbios name = fileserver
dns proxy = no
log file = /var/log/samba/log.%m
max log size = 1000
syslog = 0
panic action = /usr/share/samba/panic-action %d
encrypt passwords = true
passdb backend = smbpasswd
obey pam restrictions = yes
unix password sync = yes
passwd program = /usr/bin/passwd %u
passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssucce$
pam password change = yes
map to guest = bad user
[ExternalHDD]
comment = HDD Seagate Expansion External 2Tb
path = /media/DataR
writable = yes
printable = no
guest ok = yes
read only = no
Настроили? Идём дальше. Проверяем работоспособность всей конструкции.
Монтируем раздел (сначала размонтируем, на всякий), перезапускаем сервер
samba.
pi@raspberrypi ~ $ sudo umount /media/DataR
pi@raspberrypi ~ $ sudo mount /dev/sda3 /media/DataR
pi@raspberrypi ~ $ sudo /etc/init.d/samba restart
Если ошибок не наблюдается, то пробуем найти сервер в сети. Если и тут всё нормально, то идём дальше.
Пишем скрипт
Писать будем на Python. Интерпретатор нам уже доступен предустановленным на Raspbian. Я решил писать сразу в консоли:
pi@raspberrypi ~ $ nano shrdsk.py
Что нам нужно:
- Проверять, доступен ли IP в локальной сети
- Выполнять системные команды
- Ждать некоторое время
- Зациклить всё это дело
Итак, первым делом импортируем нужные модули:import socket as s
from time import sleep
from os import system
from errno import *
Далее всё уместится в маленьком бесконечном цикле:
while 1:
sock=s.socket(s.AF_INET,s.SOCK_STREAM)
try:
sock.connect(('192.168.0.14',1001))
system('mount /dev/sda3 /media/DataR')
system('/etc/init.d/samba restart')
except socket.error, v:
if v[0]==ECONNREFUSED:
system('mount /dev/sda3 /media/DataR')
system('/etc/init.d/samba restart')
else:
system('umount /media/DataR')
system('/etc/init.d/samba stop')
sock.close()
sleep(60)
Это минимально работоспособный вариант, но я решил его чуть
модифицировать, добавив возможность настройки и вывод отладочных
сообщений в консоль. Готовый вариант выглядит вот так:
HOST='192.168.0.14'
PORT=1001
WAITING=60
MOUNT=1
DEV='sda3'
DIR='/media/DataR'
import socket as s
from time import sleep
from os import system
from errno import *
while (1):
sock=s.socket(s.AF_INET,s.SOCK_STREAM)
try:
print "connecting..."
sock.connect((HOST,PORT))
print "socket ok"
if MOUNT:
print "mount device"
system("mount /dev/%s %s"%(DEV,DIR))
print "samba restart:"
system("/etc/init.d/samba restart")
except s.error, v:
print "socket err"
if v[0]==ECONNREFUSED:
if MOUNT:
print "mount device"
system("mount /dev/%s %s"%(DEV,DIR))
print "samba restart:"
system("/etc/init.d/samba restart")
else:
if MOUNT:
print "umount device"
system("umount %s"%DIR)
print "samba stop:"
system("/etc/init.d/samba stop")
sock.close()
print "waiting..."
sleep(WAITING)
Итоги
Получилось, что можно настроить абсолютно всё, а также отключить
(раз)монтирование раздела. Осталось прописать на устройстве статический
IP для подключения к нашей локальной сети и всё, своеобразный ключ
доступа к диску готов! Для полной автоматизации можно добавить скрипт в
автозагрузку при старте системы. Открываем системный файл rc.local:
pi@raspberrypi ~ $ sudo nano /etc/rc.local
И дописываем в него следующую строчку:
su pi -c "python /home/pi/shrdsk.py"
Путь, конечно, указываете свой.
Вот и всё, спасибо за прочтение! Это был мой первый опыт разработки под Raspberry Pi, да и под Linux вообще. Готовый файл скрипта можно загрузить с моей странички.
UPD1: спасибо, что подсказали насчёт перезагрузки и автозапуска, первое выкинул, второе поправил
http://habrahabr.ru/post/191760/
|