Инкрементный 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
      

      Вуаля. Мы получили автоматические инкрементные бэкапы при подключении нашего винта.
    Поделиться публикацией
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 36
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Уже вспомнил, как только в ленте увидел.
        Приношу извинения :) первый пост...
        • 0
          да нет, вполне нормально
          автору спасибо
        • –9
          Ужас.
          В видне можно сделать гораздо проще: autorun.inf с ссылкой на батничек с командами ntbackup-у
          • НЛО прилетело и опубликовало эту надпись здесь
          • 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 шару при появлении связи до неё?
                        • 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
                                      Как раз собираюсь переезжать :) возьму на заметку.

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.