суббота, 12 мая 2012 г.

TimeMachine: бекапим OS X Lion на Ubuntu 12.04 сервер




Если кто не знает, Time Machine - это такой замечательный бэкап-сервис из коробки для Apple OS X, тут и тут можно почитать поподробнее. Если у вас есть мак, и вы не пользуетесь "машиной времени", то это совершенно напрасно. Time Machine делает постоянные дифференциальные бэкапы, поэтому она удобна даже в случае жизни без поломок вашего HDD / SSD. Можно в любой момент открутить назад историю и восстановить случайно удаленный файл, или, что еще важнее, предыдущую версию измененного файла.

Предполагается, что пользователи будут использовать либо обычный жесткий диск (который придется целиком отдать под тайм-машину), либо специальный сетевой девайс Time Capsule. Традиционный внешний жесткий диск - решение для очень организованных людей, которые регулярно (хотя бы ежедневно) будут его подключать для автоматического бэкапа, иначе польза от тайм машины будет весьма ограничена (хотя прошлогодний бэкап все же лучше, чем совсем ничего). С тайм-капсулой будет гораздо удобнее и надежнее, так как вы не будете парится с подключением диска. Кроме функции бэкапа, она может выполнять еще и функцию сетевой шары, раздачи Wi-Fi (фактически Time Capsule - это Wi-Fi роутер с HDD). Но девайс стоит денег, и он не такой универсальный, как хотелось бы нам, гикам. К тому же, лично у меня уже есть два роутера и домашний мини-сервер (который качает торренты, дает сетевую шару по куче протоколов, стримит любые фильмы на айпад и выполняет еще 100500+ функций, кроме того, там 7.5 Тб места, и докинуть еще дисков не проблема), с тайм-капсулой было бы больше проблем. Само собой, захотелось прикрутить на мини-сервер возможность делать бэкапы тайм-машиной. И это не так сложно, о чем и будет эта заметка.

Итак у нас Ubuntu 12.04 LTS. Необходимая нам функциональность находится в пакете netatalk, это опенсорсная реализация протокола AppleTalk, также нам понадобится поставить пакет avahi-daemon для реализации zeroconf инфраструктуры в нашей сети, в данном случае это имитация любимого яблочной техникой Bonjour.

avahi-daemon можно поставить сразу:
sudo aptitude install avahi-daemon

C netatalk чуть сложнее, на момент написания заметки уже вышла релизная версия 2.2.2 с кучей новых фиксов (см. http://netatalk.sourceforge.net), а в репах убунты все еще была версия полугодовалой давности 2.2.1. Я захотел поставить версию новее (гики не ищут легких путей, да). Это можно сделать сборкой из исходников, но в тот момент можно было сделать и по-другому. На launchpad уже появился готовенький пакет 2.2.2, так что качаем его и ставим.


wget http://launchpadlibrarian.net/87307570/netatalk_2.2.1-1_amd64.deb
sudo dpkg -i netatalk_2.2.2-1_amd64.deb

Далее необходимо сконфигурировать сервисы.

Создаем файл afpd.service, который описывает конкретные сервисы раздаваемые по AppleTalk Filing Protocol демоном afpd:

sudo nano /etc/avahi/services/afpd.service

со следующим содержимым:

<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">

<service-group>
<name replace-wildcards="yes">%h</name>

<service>
<type>_afpovertcp._tcp</type>
<port>548</port>
</service>

<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=Xserve</txt-record>
</service>

</service-group>

Здесь можно изменить имя сервиса и иконку удаленного компьютера, которые отображаются в Finder на маке, за них отвечают строки

<name replace-wildcards="yes">%h</name>, где %h - имя компьютера;
<txt-record>model=Xserve</txt-record>, где вместо Xserve можно поставить: Macmini, iMac, MacPro, Xserve, MacBook, MacBookPro, MacBookAir.

Далее конфигурируем netatalk. Конфиг в /etc/default/netatalk можно не менять, все должно работать и так. А вот /etc/netatalk/AppleVolumes.default нужно изменить.

sudo nano /etc/netatalk/AppleVolumes.default

Переходим в конец файла (Ctrl + V бегать по страницам быстрее).

Добавляем строчку:
/data/backups/TimeMachine "TimeMachine" cnidscheme:dbd options:tm,upriv,usedots allow:alex

, где /data/backups/TimeMachine - путь к каталогу, в котором будут храниться бекапы;
"TimeMachine" - имя расшаренного ресурса. 
В options должно быть tm - ресурс для тайм-машины.
allow:alex - пользователь, имеющий доступ к каталогу. Он (в данном случае alex) должен быть на вашем сервере (я еще для удобства сделал так, чтобы пользователь на убунте и на маке имел одно имя), создать пользователя можно с помощью команды useradd.

Можно добавить еще просто разделяемую шару, например:

/data/common "Common" cnidscheme:dbd options:usedots,upriv dperm:0776 fperm:0666 allow:@shares

Тут в опциях уже не надо указывать tm.
Здесь dperm:0777 fperm:0666 - права на создаваемые каталоги и файлы,
allow:@shares  - доступ только пользователям входящим в группу shares (создать группу можно  с помощью groupadd , а добавить пользователя в группу usermod -a -G groupname username)

Права и группа - для того, чтобы данной шарой можно было удобно пользоваться несколькими людьми. Для этого людям создаются учетки, и им добавляется группа shares. К сожалению, я не нашел возможности сделать как в самбе, чтобы новые файлы создавались от имени группы, поэтому пришлось дать полные права для others, иначе файлы, созданные одним человеком не могли бы редактироваться другими.

Рестартуем сервис:

sudo service netatalk restart

Перезапуск avahi

sudo service avahi-daemon restart

Вот в общем и все.

PS
Хотя нет, без напильника не обошлось (это же линукс) :trollface: . Т.е. сразу нифига не заработало, симптом такой: в файндере пробуем подключиться к шаре, а он говорит, что там ничего и нет, куда подключаться? Оказалось, что afpd не стартанул толком.

cat /var/log/syslog 

давал следующее:

May 12 03:13:26 mini-server afpd[13367]: ===============================================================
May 12 03:13:26 mini-server afpd[13367]: INTERNAL ERROR: Signal 11 in pid 13367 (2.2.2)
May 12 03:13:26 mini-server afpd[13367]: ===============================================================
May 12 03:13:26 mini-server afpd[13367]: BACKTRACE: 3 stack frames:
May 12 03:13:26 mini-server afpd[13367]:  #0 /usr/sbin/afpd(netatalk_panic+0x1c) [0x7fd5ac5e6b0c]
May 12 03:13:26 mini-server afpd[13367]:  #1 /usr/sbin/afpd(+0x53c0c) [0x7fd5ac5e6c0c]
May 12 03:13:26 mini-server afpd[13367]:  #2 /lib/x86_64-linux-gnu/libc.so.6(+0x364c0) [0x7fd5aaf444c0]

Гугление проблемы дало вариант решения. Открываем /etc/netatalk/afpd.conf:

sudo nano /etc/netatalk/afpd.conf

и меняем самую последнюю строчку на
- -tcp -noddp -uamlist uams_dhx.so,uams_dhx2_passwd.so -nosavepassword


Проблема оказалась в библиотеке uams_dhx2.so, которая не дружит с Lion, помогла замена на uams_dhx2_passwd.so.

понедельник, 13 июня 2011 г.

Адаптация seeker (утилита замеряющая среднее время поиска) для Mac OS X

Исходная утилита seeker описана тут: http://www.linuxinsight.com/how_fast_is_your_disk.html, но под Mac OS она не компилируется. Ниже представлена небольшая модификация исправляющая сей недочет.

seeker.c


#define _LARGEFILE64_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>

#ifdef __APPLE__
#include <sys/disk.h>
#define off64_t off_t
#define lseek64 lseek
#define BLKGETSIZE DKIOCGETBLOCKCOUNT
#else
#include <linux/fs.h>
#endif

#define BLOCKSIZE 512
#define TIMEOUT 30

int count;
time_t start;

void done()
{
time_t end;
    
time(&end);
    
if (end < start + TIMEOUT) {
printf(".");
alarm(1);
return;
}
    
if (count) {
        printf(".\nResults: %d seeks/second, %.2f ms random access time\n",
               count / TIMEOUT, 1000.0 * TIMEOUT / count);
}
exit(EXIT_SUCCESS);
}

void handle(const char *string, int error)
{
if (error) {
perror(string);
exit(EXIT_FAILURE);
}
}

int main(int argc, char **argv)
{
char buffer[BLOCKSIZE];
int fd, retval;
unsigned long numblocks;
off64_t offset;
    
setvbuf(stdout, NULL, _IONBF, 0);
    
printf("Seeker v2.0, 2007-01-15, "
      "http://www.linuxinsight.com/how_fast_is_your_disk.html\n");
    
if (argc != 2) {
printf("Usage: seeker <raw disk device>\n");
exit(EXIT_SUCCESS);
}
    
fd = open(argv[1], O_RDONLY);
handle("open", fd < 0);
    
retval = ioctl(fd, BLKGETSIZE, &numblocks);
handle("ioctl", retval == -1);
printf("Benchmarking %s [%luMB], wait %d seconds",
      argv[1], numblocks / 2048, TIMEOUT);
    
time(&start);
srand(start);
signal(SIGALRM, &done);
alarm(1);
    
for (;;) {
offset = (off64_t) numblocks * random() / RAND_MAX;
retval = lseek64(fd, BLOCKSIZE * offset, SEEK_SET);
handle("lseek64", retval == (off64_t) -1);
retval = read(fd, buffer, BLOCKSIZE);
handle("read", retval < 0);
count++;
}
/* notreached */
}


Изменения: off64_t и lseek64 под BSD не нужны, off_t и так уже 64 битный,  плюс другой заголовочный файл и другое имя константы

понедельник, 9 мая 2011 г.

ARM vs Intel Atom (часть 1)

С давних пор ARM и x86 шли разными путями, решения ARM использовался в основном в embedded решениях (терминалы, маршрутизаторы, КПК, телефоны), а x86 - в ПК и ноутбуках. ARM отличается энергоэффективностью, но ценой уменьшения производительности, а x86 - большей производительностью, но гораздо меньшей энергоэффективностью.

Но с недавних пор, компания Intel стала активнее интересоваться мобильным рынком и выпустила процессоры Atom, при проектировании которых во главу угла ставилась энергоэффективность, точек соприкосновения стало больше. В тоже время процессоры ARM становятся с каждым годом все производительнее. Сейчас ARM активно используется в смартфонах и планшетах (на различных "мобильных" операционных системах, как-то: iOS, Android, WinCE и т.д.), Atom - в нетбуках и планшетах (в основном на базе Windows 7, реже Android).

Вот почему мне стало интересно сравнить производительность современных ARM и Atom. Но как можно сравнить производительность различных архитектур? Можно было бы найти программы, работающие по одному и тому же алгоритму под обе платформы, в идеале код должен быть одинаковым, что усложняет задачу. Или написать такой тестовый набор самому, что я и решил сделать :).

Чтобы не писать совсем уж искусственные тесты, я решил использовать известные алгоритмы. Для начала мой выбор пал на алгоритм сжатия данных, для его осуществления выбрал известную кроссплатформенную библиотеку zlib. Эта библиотека часто используется разработчиками и написана на чистом Си, без специфических оптимизаций под какую-либо платформу.

Для тестирования использовал имеющиеся в наличии устройства.

ARM: Apple iPad 2, работающий на процессоре A5 (двухядерный Cortex A9) на частоте 1 ГГц, операционная система iOS.

Atom: домашний минисервер на базе материнской платы Intel D510MO c процессором D510 (два ядра + hyper-threading) на частоте 1.66 ГГц, операционная система Ubuntu 10.04.2 LTS 32-бит.

В основе программы - функция, использующая zlib:

void compress_file(const char *fname_in, const char *fname_out)
{
    FILE *f_in = fopen(fname_in, "rb");
    gzFile fz_out = gzopen(fname_out, "wb9"); //используем максимальную степень сжатия - 9
    
    char buf[8*1024];
    
    size_t byte_read;
    while ((byte_read = fread(buf, 1sizeof(buf), f_in)) > 0)
    {
        gzwrite(fz_out, buf, byte_read);
    }
    
    fclose(f_in);
    gzclose(fz_out);
}

Программа однопоточная, задействуется только одно ядро.

Время работы под iOS замерялось с помощью [NSDate timeIntervalSinceReferenceDate], а на Ubuntu - с помощью функции time.

На iOS применялся стандартный компилятор для XCode 4 - gcc 4.2 с опциями -O2 -mtune=cortex-a8 -march=armv7-a (но mtune и march особого влияния не оказали, настройки по умолчанию armv7 видимо достаточно), на Ubuntu - gcc 4.4 с -O2 -mtune=native -march=native.

Осуществлялась обработка 300Мб текстового файла, на выходе получился 70Мб файл.

Результаты:
Atom D510 ~290 сек
A5 ~440 сек

D510 быстрее A5 в 1,5 раза. Но учитывая что тактовая частота D510 больше в 1.66 раз, производительность же на единицу частоты у A5 получается несколько выше. Интересные результаты, не так ли? :]