Инкрементный Backup при подключении USB HDD в Ubuntu

    Наконец-то я нашел время заняться свежеприехавшей железкой — USB винт на 500Gb. Этот пост может быть полезен всем, кто задумывался о надежном и удобном бэкапе данных, требующем минимальных затрат усилий.
    Итак приступим.


    Дано: USB HDD, laptop with Ubuntu 7.10, lots of useful data :)

    Хочется: Автоматический инкрементный бэкап, при подключении конкретного USB HDD, при условии, что со времени последнего бэкапа прошло не менее N-минут.

    Инструменты:

    1. sbackup — отличная софтинка на питоне, работает посредством rdiff-backup, умеет писать в локальные папки и в SSH сессию. Архивирует данные. Сохраняет список установленных пакетов.
      udev rules file — тут мы хитро определяем и монтируем наш диск
      some bash scripts — проверяем, а нужно ли нам бэкапиться


      Приступим:

      Перво-наперво нам нужно заставить udev определять наш конкретный винт. Сделать это очень просто. Создаем файл
      /etc/udev/rules.d/94-usb-backup.rules Номер 94 выбран как 95-hal.rules -1. Это важно, т.к. лучше свершить наши черные дела до того как HAL опознает устройство.

      --/etc/udev/rules.d/94-usb-backup.rules--
      SUBSYSTEM=="block", ENV{DEVTYPE}=="partition", SYSFS{idProduct}=="2339", SYSFS{idVendor}=="152d", NAME="backup", RUN+="/usr/local/bin/usb-backup"
      


      Далее нужно определиться по каким параметрам будем распознавать устройство. Если нужно бэкапиться только на конкретный определенный винт, то выбираем максимально уникальную совокупность параметров.Мне хватило пары idProduct и idVendor. Для верности можно добавить например iSerial (спасибо small_jam и spiritedflow за замечания). Значения idProduct и idVendor нужно узнавать для каждого конкретного устройства при помощи команды

      $ lsusb –v
      

      И получим что то в этом роде
      ...
      Bus 005 Device 089: ID 152d:2339 
      Device Descriptor:
        bLength                18
        bDescriptorType         1
        bcdUSB               2.00
        bDeviceClass            0 (Defined at Interface level)
        bDeviceSubClass         0
        bDeviceProtocol         0
        bMaxPacketSize0        64
        idVendor           0x152d
        idProduct          0x2339
        bcdDevice            1.00
        iManufacturer           1 JMicron
        iProduct                2 USB to ATA/ATAPI Bridge
        iSerial                 5 901EFFFFFFFF
        bNumConfigurations      1
        Configuration Descriptor:
          bLength                 9
          bDescriptorType         2
          wTotalLength           32
          bNumInterfaces          1
          bConfigurationValue     1
      ...
      

      NAME=«backup» означает, что монтироваться будет наш винт в /dev/backup
      RUN+="/usr/local/bin/usb-backup" — указываем какой скрипт выполнять при подключении. Важно! Тут пишем именно имя скрипта, а не команду, например если написать RUN+="/usr/local/bin/usb-backup&" работать не будет.
      К скрипту мы вернемся чуть позже. Создадим пока заглушку и дадим права на выполнение.
      --/usr/local/bin/usb-backup--
      #!/bin/bash
      

      Сейчас закончим с монтированием.
      Чтобы устройство автоматически смонтировалось добавим строчку в /etc/fstab
      --/etc/fstab/--
      ...
      /dev/backup /media/backup ext3 users,atime,noauto,rw,nodev,exec,nosuid 0 0
      

      Это при условии, что файловая система у нас на винте ext3.

      Далее можно тестить. Отключаем винт. Сохраняем все конфиги. Делаем /etc/init.d/udev restart
      Подключаем винт. Смотрим. Должно было смонтироваться в /media/backup.

      Теперь настроим sbackup. Он есть в репозитарии поставить можно при помощи apt-get install sbackup
      В конфиге /etc/sbackup.conf достаточно информации по настройке. Важно указать ту же target директорию, что и в скриптах ниже.

      Далее возвращаемся к скрипту /usr/local/bin/usb-backup
      У него есть одна особенность. Пока он не выполнится монтирование дальше не пойдет. Поэтому применяем обходной маневр.
      --/usr/local/bin/usb-backup--
      #!/bin/bash
      /usr/local/bin/usb-backup-script &
      

      Запускаем второй скрипт в фоне. Он то и будет делать всю работу.
      --/usr/local/bin/usb-backup-script--
      #!/bin/bash
      BCPDIR=/media/backup/backup_storage/  #это директория с бекапами
      for i in `seq 1 10`;
      do
       if [ -e $BCPDIR ] # смотрим подмонтировалось ли?
        then # считаем файлы младше 180 минут не заходя в директории
         if [ ` find $BCPDIR -maxdepth 1 -mmin -180 | grep -v ^$BCPDIR$ | grep . -c` -eq 0 ];
          then
           sbackupd # запускаем бэкап
          fi
      
      
          break        # циклиться теперь не нужно
       fi
       sleep 1 # ждем секудну, пока подмонтируется (у меня обычно пара секунд)
      done
      

      Вуаля. Мы получили автоматические инкрементные бэкапы при подключении нашего винта.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 36

    • UFO just landed and posted this here
        0
        Уже вспомнил, как только в ленте увидел.
        Приношу извинения :) первый пост...
          0
          да нет, вполне нормально
          автору спасибо
          –9
          Ужас.
          В видне можно сделать гораздо проще: autorun.inf с ссылкой на батничек с командами ntbackup-у
          • UFO just landed and posted this here
              –1
              jedem das seine
              0
              Задумка немного другая - не винт привязать, а систему научить распознавать устройства и обрабатывать их. То есть в идеале устройство куда бекапимся - любое и совершенно не важно что на нем лежит.
              К тому же ntbackup значительно уступает по функциональности sbackup.
                –1
                хм, ко мне в гости ходит много народу, для них есть гостевой ноут
                но вот если я буду юзать подобную шнягу, то кто-то может просто унести данные и я об этом знать не буду
                вопрос безопастности, думаю ход мыслей ты понял
                в целом реализация супер
                  0
                  Можно решить как я уже описал добавлением параметров для уникальности, например серийника.
                    0
                    Но с другой стороны, если использовать autorun.inf, то любой получивший доступ к usb с большой вероятностью сможет сделать с системой что угодно.
                0
                RUN+="/usr/local/bin/usb-backup"

                это автозапуск что-ли?
                  0
                  Это не совсем автозапуск. Этот скрипт выполняется если устройство подходит под описанные условия, важно что он выполняется с привилегиями root'а в отличие от автозапуска который выполняется от текущего пользователя. Таким образом можно сделать более полный бекап т.к. прав доступа хватит на все.
                  +1
                  Может быть вместо idVendor/idProduct, которые по идее одинаковые для всех хардов одной модели, стоит попробовать прязаться к серийнику или к UUID раздела? А то действительно, кто-нибудь вставит такой же винт и унесет бэкап.
                    0
                    Согласен, полностью. Тут каждый для себя настраивает совокупность параметров для уникальности.
                    Пожалуй стоит это упомянуть.
                    0
                    ОтличныйТопикАккорд — плюсы вкарму автору, топику и вмемориз.
                      +4
                      Всем спасибо за плюсы. Перенес топик в Убунтариум. Думаю ему там самое место.

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

                      Для решения этой проблемы я написал немножко кода на питоне. Пришлось обойти пару узких мест (связанных с тем, что запускается это от root'а).

                      Жить второму топику?
                        +1
                        Однозначно жить. Тем более, что данная вещь применима не только в Убунте. Предлагаю перенести в Linux для всех.
                          0
                          мало того, она применима не только в линукс (-:
                        0
                        Не понял, а где собственно выполняется монтирование?
                          0
                          Монтирование выполняется автоматически HAL'ом на основании информации из fstab. Скрипт запускается в фоне и ждет пока все примонтируется.
                            0
                            ЗдОрово, не знал, что HAL это умеет
                          0
                          Это 5!!! Автору + в карму!
                            0
                            раз автор так искушен в вопросах бекапа, у меня есть реквест на следующий хабратопик: а как делать автоматический бекап на smb шару при появлении связи до неё?
                              +1
                              crontab + touch и его EXIT STATUS
                              0
                              Не плохо, правда у меня всё несколько проще:
                              ~ $ cat bin/mybkp.sh
                              #!/bin/bash

                              tar zvcf /media/backup/backup-`date '+%F'`.tar.gz --listed-incremental=/media/backup/backup.snar ~/ --exclude=Videos --exclude=Music --exclude=Public --exclude=.wine --exclude=.thumbnails --exclude=.VirtualBox --exclude=.cache --exclude=.ies4linux --exclude=/home/redchrom/.mozilla/firefox/*/Cache --exclude=/home/redchrom/.liferea_1.4/mozilla/liferea/Cache/ --exclude=.rnd --exclude=/home/redchrom/workspace/.metadata

                              И ручками запускаю :)
                                0
                                странно, а у меня не работает, все равно монтируется как обычно /media/disk, /dev/backup не появляется
                                  0
                                  помогло вот это:
                                  BUS=="usb", SYSFS{idVendor}=="04cf", SYSFS{idProduct}=="8818", ATTRS{serial}=="100", KERNEL=="sd?1", NAME="backup", GROUP="storage"
                                  только все равно пытается примонтировать в /media/backup и выходит ошибка что нету директории, как бы это отключить :)
                                  0
                                  а чтобы сделать то же, но с помощью rsync на удаленный сервер, что надо поменять? :)
                                    0
                                    То же - это что? Просто функциональность rsync есть в sbackup. Чтобы бэкапиться на удаленный сервер надо его настройки править. Но смысла я тут большого не вижу... Фишка была чтобы обработать событие подключения конкретного устройства и бэкапнуться на него... А в сеть можно и без всего этого. Тем же кроном как советуют выше проверить доступность сервака и запустить скрипт. Разве что в два места бэкапиться при подключении... на винт и в сеть.
                                      0
                                      то же - инкрементный бекап
                                    0
                                    спасибо, отличная заметка.
                                      0
                                      Спасибо. Очень интересно.
                                      Не подскажите, можно ли выполнить скрипт бэкапа не от рута а от текущего пользователя

                                      Кстати, udev можно не перезапускать — он и так подхватывает настройки.
                                        0
                                        Не от рута не получится sbackupd ругнется. Теоретически можно наверное, но тогда нельзя будет системные файлики бекапить.
                                          0
                                          Я хочу немножко для другого это приспособить. Идеальный вариант был бы таков — если мой пользователь залогинен, то копируем файлы, если нет то не копируем.
                                          Кстати, я вчера пробовал провернуть хитрость с udev когда девайс разбит на два раздела. Оказалось, у них вывод udevinfo почти идентичен, за ислючением размера и некоторых параметров, которые меняются при каждом подключении.
                                        +1
                                        Предупреждение для тех, кто будет делать это на убунту 9.04. сегодня пару часов помучался пока мне дошло, что в 9.04 правила Udev переехали из /ect/udev/rules.d в /lib/udev/rules.d/. а в реадми из /etc/udev/rules.d нетёб этом ни слова.
                                          0
                                          Как раз собираюсь переезжать :) возьму на заметку.

                                        Only users with full accounts can post comments. Log in, please.