UMGUM.COM (лучше) 

Bluetooth + Mobilephone + Backup + OBEXFS + Rsync ( Простейшее автоматическое резервное копирование файловой системы мобильного телефона. )

16 июня 2010  (обновлено 27 мая 2017)

Эта публикация отнесена в архив. Она неактуальна.

OS: Debian Linux.

Задача элементарна: обеспечить автоматическое регулярное резервирование информации располагающейся в файловой системе мобильного телефона.

После того, как производители электроники под давлением карьеристов и "болтологов" от экологии повально перешли на без свинцовый припой, выход из строя мелких устройств стал непредсказуемым явлением; теперь устройство может прослужить пять лет, а может прийти в негодность и утянуть в небытие накопленные на нем данные на третий день эксплуатации. Не то, чтобы для меня мобильные телефон являлся особо ценным предметом, но в некоторых случаях - это единственный носитель информации объёмом под два-три Гигабайта. В общем-то, обидно потерять все это за раз.

Для начала мы должны иметь мобильный телефон с поддержкой протокола OBEX, подключённый и сопряжённый с компьютером по Bluetooth.


Временно переводим сотовый телефон в режим видимости всем окружающим по протоколу Bluetooth.

Сканируем устройство на предмет поддерживаемых технологий (MAC в формате "xx:xx:xx:xx:xx:xx"):

# sdptool browse mac.address

....
Service Name: OBEX File Transfer
....
    Channel: 10
....

Нас будут интересовать блок описания поддержки технологии OBEX, передачи и манипулирования данными. Особенно, номер канала, по которому необходимо обращаться к оборудованию для доступа к этим сервисам; в нашем случае это номер 10.

Инсталлируем набор утилит, реализующих монтирование файловой системы мобильного телефона с помощью OBEX по самым разным интерфейсам.

К сожалению, доступная в репозитории Debian Lenny версия obexfs 0.10 более или менее корректно работала в режиме только последовательного чтения. Работа с удалённой файловой системой осуществляется в "блокирующемся" режиме, то есть, при исполнении какой либо операции вроде чтения содержимого директории, копирования, манипулирования данными доступ к файловой системе полностью блокируется, параллельные операции не допускаются. Применение опции включения неблокирующегося режима никак не влияет на ситуацию. Мало того, организация блокировок и уведомлений о состоянии мягко говоря странная, вплоть до того, что ряд приложений, вроде Midnight Commander вообще толком работать не может.
Суть проблемы в том, что сразу после начала копирования на удалённую файловую систему приложению сообщается о том, что копирование как таковое прошло успешно, при том, что реально оно ещё продолжается (полагаю, что в это время данные переносятся из буфера на реальное устройство). Так вот, если приложение пытается применить к этому файлу какую либо операцию, например, установить для него права доступа, проверить успешность проведённой операции, то получает от удалённой файловой системы выговор на предмет невозможности доступа к файлу, что ещё не с копировался окончательно; отработать эту ситуацию приложение не может и обращается к пользователю за советом, а то и не за одним, и так при каждой операции. Установка при монтировании файловой системы опций применения синхронной записи ситуации не меняет.
Ещё одна критичная ошибка, не позволяющая использовать "стабильную" (хе) версию из репозитория в том, что директории и файлы с не латинскими символами не отображаются в точках монтирования, а при попытке прямого к ним обращения - ошибки и отказ в доступе. При чём грешить на FUSE не позволяет тот факт, что при использовании SSHFS работа с файлами таких проблем не доставляет.

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

Чтобы не завалить файловую систему неуправляемым мусором из библиотек, исполняемых файлов и ресурсов, будем использовать сборщик пакетов, утилиту checkinstall:

# aptitude install checkinstall

Для сборки утилит набора OBEX из исходных кодов потребуется предварительно установить ряд пакетов удовлетворяющих зависимости:

# aptitude install fuse-utils libfuse-dev libobexftp-dev libbluetooth-dev libusb-dev pkg-config python-dev ruby-dev tcl-dev

Идём по адресу http://dev.zuckschwerdt.org/openobex/wiki/ObexDownloads и берем самые свежие пакеты исходных кодов obex, obexftp и obexfs (в моем случае это версии 1.5, 0.23 и 0.12):

# cd /usr/src
# wget http://www.kernel.org/pub/linux/bluetooth/openobex-1.5.tar.gz
# wget http://downloads.sourceforge.net/project/openobex/obexftp/0.23/obexftp-0.23.tar.bz2
# wget http://downloads.sourceforge.net/project/openobex/obexfs/0.12/obexfs-0.12.tar.gz

Распаковываем архивы:

# tar -xvf openobex-1.5.tar.gz
# tar -xvf obexftp-0.23.tar.bz2
# tar -xvf obexfs-0.12.tar.gz

Переходим в директории с исходными кодами и проверяем, удовлетворяет ли наша система зависимостям собираемого приложения, пробуем произвести предварительное конфигурирование пакета на предмет обнаружения ошибок, конфигурируем и собираем пакеты:

# cd /usr/src/openobex-1.5
# ./configure --no-create --prefix=/usr
# ./configure --prefix=/usr
# checkinstall -D --install=no --pkggroup=OBEX --pkgname=openobex-fresh --pkgversion=1.5 --pkgrelease=1 --pkgsource=http://downloads.sourceforge.net/project/openobex/ --maintainer=me@domain.name --nodoc make install
# dpkg -i /usr/src/openobex-1.5/openobex-fresh_1.5-1_amd64.deb

# cd /usr/src/obexftp-0.23
# ./configure --no-create --prefix=/usr
# cd /usr/src/obexftp-0.23
# ./configure --prefix=/usr
# checkinstall -D --install=no --pkggroup=OBEX --pkgname=obexftp-fresh --pkgversion=0.23 --pkgrelease=1 --pkgsource=http://downloads.sourceforge.net/project/openobex/ --maintainer=me@domain.name --nodoc make install
# dpkg -i /usr/src/obexftp-0.23/obexftp-fresh_0.23-1_amd64.deb

# cd /usr/src/obexfs-0.12
# ./configure --no-create --prefix=/usr
# cd /usr/src/obexfs-0.12
# ./configure --prefix=/usr
# checkinstall -D --install=no --pkggroup=OBEX --pkgname=obexfs-fresh --pkgversion=0.12 --pkgrelease=1 --pkgsource=http://downloads.sourceforge.net/project/openobex/ --maintainer=me@domain.name --nodoc make install
# dpkg -i /usr/src/obexfs-0.12/obexfs-fresh_0.12-1_amd64.deb

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

Монтируем по MAC адресу мобильного телефона (MAC в формате "xx:xx:xx:xx:xx:xx"):

# obexfs -b mac.address -B 10 -- -o noatime /mnt/point

Отмонтируем:

# fusermount -u /mnt/point

...или:

# umount /mnt/point

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

Инсталлируем утилиту инкрементального резервного копирования:

# aptitude install rsync

Пишем простенький скрипт (предполагается, что к компьютеру подключёно только одно, целевое, мобильное устройство), что будет осуществлять подключение к мобильному телефону по протоколу Bluetooth и копировать изменённые данные с телефона на компьютер:

# mkdir -p /etc/custom/bluetooth
# touch /etc/custom/bluetooth/backup.mobile0.sh
# chmod ug+x /etc/custom/bluetooth/backup.mobile0.sh

#!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

DATE=`date +"%Y-%m-%d %H:%M:%S"`
# MAC в формате "xx:xx:xx:xx:xx:xx"
MAC="mac.mobile.phone"
# Полный путь к директориям указывается без финального слэша
POINT="mount.point.directory"
BACKUP="backup.directory"

if [ ! "`ls /dev | grep rfcomm0`" ]
then
  /usr/sbin/hciconfig hci0 up
  echo "$DATE Запускаем Bluetooth ..."
  sleep 3
fi

if [ ! "`l2ping -t 3 -c 3 $MAC 2>&1 | grep -i failed`" ] && [ ! "`l2ping -t 3 -c 3 $MAC 2>&1 | grep -i down`" ]
then
  if [ "`mount | grep -i obexfs | grep -i $POINT`" ]
  then
    # От монтируем устройство (скорее всего это следы предыдущей незавершённой сессии)
    umount -f $POINT
    sleep 5
  fi

  # Исходя из того предположения, что мы здесь одни - уничтожаем все незавершённые процессы прежней сессии (по хорошему нужно бы искать по PID)
  killall rsync
  killall obexfs
  mkdir -p $POINT
  echo "$DATE Монтируем устройство с MAC: $MAC ..."
  obexfs -b $MAC -B 10 -- -o noatime $POINT
  sleep 5
  echo "$DATE Приступаем к синхронизации ..."
  rsync -av $POINT/ $BACKUP
  umount $POINT
else
  # Огорчаемся тому, что устройство не доступно в данный момент
  echo "$DATE Device with MAC: $MAC is not available through Bluetooth on this host"
fi

exit 0

Понятно, что резервирование инкрементальное и замещающее, не гарантирующее восстановления тех старых файлов, что были затёрты новыми, с таким же именем, но, в конце концов, если мы удалили файл с мобильного телефона и разместили там другой с таким же именем, не значит ли это то, что старый файл нам не был нужен? В конце концов мы не архивы фондовой биржи делаем, а "зеркало" файловой системы не особо значимого мобильного устройства.

В первый раз процедура копирования довольно таки затяжная, в зависимости от количества данных, что нужно скопировать. В дальнейшем, инкрементальных характер работы rsync значительно ускорит операцию "зеркалирования".
Первичное копирование данных большого объёма - операция затратная как с точки зрения времени, так и ресурсов процессора и беспроводного интерфейса мобильного устройства. Затратна настолько, что один из моих стареньких и замученных жизнью телефонов буквально не выдерживал нагрузки и выключался.

Размещаем в таблице crontab указание на периодический запуск синхронизации. Не знаю, как у кого, но у меня график работы за компьютером весьма непостоянный и с точностью предсказать, когда именно я буду работать, да ещё и иметь рядом телефон со включённым Bluetooth проблематично. Пришлось выставить особый режим с плавающей датой старта скрипта с помощью периода между попытками в пять часов в надежде поймать возможность автоматического резервирования.

# cat /etc/crontab

....
0  */5  * * *   root    /etc/custom/bluetooth/backup.mobile0.sh &
....

И, очень медленный этот интерфейс Bluetooth, ну очень.


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )