Организация сервера на примере Rsync

В данной лекции мы рассмотрим обеспечение запуска серверного ПО в Unix-подобных системах на примере программы Rsync. Начнем мы, однако, с описания работы этой программы как таковой.

Общие сведения об Rsync

Основное предназначение Rsync — эффективная односторонняя синхронизация файловых архивов через сеть. Rsync используется, например, для периодического обновления зеркал таких архивов.

Эффективность работы Rsync обеспечивается:

Rsync можно использовать и для локальной синхронизации архивов. В случае размещения копии на носителе на основе flash-памяти это позволяет, среди прочего, снизить износ (т. е. расход циклов перезаписи) устройства.

В примерах ниже мы предполагаем некоторую степень знакомства с Unix-подобными системами (в частности — Debian GNU/Linux) — хотя бы в объеме лабораторной работы «Основы взаимодействия с ОС».

Пример: рекурсивное копирование содержимого директории alice в директорию dave; при повторном копировании передается значительно (в данном случае — в 280 038 раз) меньший объем данных.
$ ls -gGR -- alice 
alice:
total 0
drwxr-xr-x 3       80 Apr 23 04:40 bob
-rw-r--r-- 1 14727168 Apr 23 04:40 onefile

alice/bob:
total 0
-rw-r--r-- 1 28023808 Apr 23 04:40 anotherfile
drwxr-xr-x 2       60 Apr 23 04:40 charlie

alice/bob/charlie:
total 0
-rw-r--r-- 1 7936000 Apr 23 04:40 thirdfile
$ rsync -v --sparse -brOtHx --suffix=.~$(date +%s)~ \
      -- alice/ dave/ 
sending incremental file list
created directory dave
./
onefile
bob/
bob/anotherfile
bob/charlie/
bob/charlie/thirdfile

sent 50,699,653 bytes  received 123 bytes  101,399,552.00 bytes/sec
total size is 50,686,976  speedup is 1.00
$ ls -gGR -- dave
dave:
total 0
drwxr-xr-x 3       80 Apr 23 04:40 bob
-rw-r--r-- 1 14727168 Apr 23 04:40 onefile

dave/bob:
total 0
-rw-r--r-- 1 28023808 Apr 23 04:40 anotherfile
drwxr-xr-x 2       60 Apr 23 04:40 charlie

dave/bob/charlie:
total 0
-rw-r--r-- 1 7936000 Apr 23 04:40 thirdfile
$ rsync -v --sparse -brOtH --suffix=.~$(date +%s)~ \
      -- alice/ dave/ 
sending incremental file list

sent 167 bytes  received 14 bytes  362.00 bytes/sec
total size is 50,686,976  speedup is 280,038.54
$ 

Все передаваемые выше файлы являются разряженными и фактически содержат лишь информацию о размере, но не какие-либо данные, заполняющие этот размер — что и объясняет total 0 в выводе ls. Опция rsync --sparse позволяет принимающей стороне выявлять такие файлы и сохранять свойство разряженности, однако протокол Rsync не поддерживает более эффективной их обработки и требует фактической передачи «несуществующего» содержимого. Отметим, что создать «пустой» разряженный файл заданного размера можно командой truncate.

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

Пример: обновление материала на локальном HTTP-сервере по личной «рабочей копии» с указанием имен файлов для копирования.
bash$ rsync -cb -rOtHx --suffix=.~$(date +%s)~ \
          --backup-dir=.rsync-backup --exclude=\*~ \
          --include=inco-"$(date +%Y)"/{,"[algx]"/} \
          --include=inco-2020/{README,a/{bonus,report,scoring},\
basin,cry,debian,fs,g/{list,web-cat},internet,\
l/{exampled,inet,sockets},misc,ssh,web}.ru.xhtml \
          --exclude=\* \
          -- ~/private/bits/ ~/public/ 

Использование процессов и межпроцессного взаимодействия

Ради единообразия, использование Rsync всегда предполагает наличие двух процессов: клиента и сервера. Здесь возможны три основных случая.

  1. При копировании между директориями одной системы оба процесса будут просто порождены обычным системным вызовом fork (или clone.)

  2. При использовании SSH (или иного подобного протокола удаленного выполнения команд) — один из порожденных процессов будет замещен (execve) SSH-клиентом (например, ssh из состава OpenSSH), который, в свою очередь, запустит один из процессов на удаленной системе.

  3. Наконец, при использовании Rsync как сервиса Internet, сервер будет ожидать соединения на каком-либо порту. Стандартным (т. е. внесенным в соответствующий реестр IANA) для Rsync является порт 873 TCP.

    Этот случай наиболее интересен в контексте данной лекции, и мы более подробно рассмотрим его ниже.

    Такое использование Rsync является предметом соответствующего раздела лабораторной работы «Internet».

Строго говоря, возможен и четвертый случай: оба процесса выполняются на удаленных системах, обмениваясь данными через локальную. Такой вариант, очевидно, менее эффективен (любые данные передаются по сети дважды) и не поддерживается непосредственно командой rsync. Что, впрочем, при желании можно обойти, например используя Socat.

Пример: обновление материала на удаленном HTTP-сервере по SSH.
bash$ rsync -cb -rOtHx --suffix=.~$(date +%s)~ \
          --backup-dir=.rsync-backup --exclude=\*~ \
          --include=inco-"$(date +%Y)"/{,"[algx]"/}{,\*.xhtml} \
          --exclude=\* \
          -- ~/public/ www.example.com:public/ 
Пример: получение списка модулей (директорий верхнего уровня) удаленного Rsync-сервера.
$ rsync -- rsync://ftp.nluug.nl/ 
pub             /pub hierarchy
site            /site hierarchy
vol             /vol hierarchy
blender         blender

Пример: создание и обновление частичного локального зеркала NetBSD с удаленного сервера.
$ rsync -v -brOtH --suffix=.~$(date +%s)~ --exclude=\*~ \
      --include=NetBSD-9.0/{,amd64/} --include=INSTALL.html \
      --include={CHANGES,README}\* --include=LAST_MINUTE \
      --exclude=\* \
      -- rsync://ftp.nluug.nl/netbsd/ public/download/netbsd/ 
receiving incremental file list
created directory public/download/netbsd
./
README
README.export-control
NetBSD-9.0/
NetBSD-9.0/CHANGES
NetBSD-9.0/CHANGES-9.0
NetBSD-9.0/CHANGES.prev
NetBSD-9.0/LAST_MINUTE
NetBSD-9.0/README.files
NetBSD-9.0/amd64/
NetBSD-9.0/amd64/INSTALL.html

sent 316 bytes  received 1,135,867 bytes  48,348.21 bytes/sec
total size is 1,134,956  speedup is 1.00
$ rsync -v -brOtH --suffix=.~$(date +%s)~ --exclude=\*~ \
      --include=NetBSD-9.0/{,amd64/} --include=INSTALL.html \
      --include={CHANGES,README}\* --include=LAST_MINUTE \
      --exclude=\* \
      -- rsync://ftp.nluug.nl/netbsd/ public/download/netbsd/ 
receiving incremental file list

sent 143 bytes  received 298 bytes  26.73 bytes/sec
total size is 1,134,956  speedup is 2,573.60
$ 

Запуск Internet-сервера

Вспомним, что одним из простых способов организации сервера является использование управляющего процесса, владеющего ожидающим (англ. listening) гнездом и порождающего дочерние процессы по мере поступления запросов на установление соединения — причем для обработки каждого соединения создается отдельный процесс.

Таким управляющим процессом для Rsync может быть, например:

Работа Rsync в этом режиме несколько отличается от других случаев выше — когда выполняемая локально команда rsync непосредственно определяет аргументы командной строки для порождаемых Rsync-процессов (хотя бы уже по той причине, что протокол TCP сам по себе не предусматривает механизма для передачи таких аргументов.) А именно:

Рассмотрим запуск сервера Rsync на следующих примерах.

Пример файла rsyncd.conf.
### .rsyncd.conf  -*- Conf -*-

log file    = /home/private/users/jrh/.rsync.log

[alice]
    path        = /home/public/project1/alice
    comment     = Alice’s own data
    exclude     = .rsync-backup *~ .htaccess .*/ .*.*

[dave]
    path        = /home/public/users/dave
    comment     = Dave’s copy
    exclude     = .rsync-backup *~ .htaccess .*/ .*.*

### .rsyncd.conf ends here
Пример: организация сервера Rsync с использованием Socat и с использованием лишь опции --daemon.
$ setsid -- socat  TCP6:8873,fork \
      EXEC:"rsync --daemon --config=${HOME}/.rsyncd.conf" 
$ rsync --port=7873 --daemon --config="$HOME"/.rsyncd.conf 
$ 
Пример: обращение к созданным серверам.
$ rsync -- rsync://ip6-localhost:8873/ 
alice           Alice's own data
dave            Dave's copy
$ rsync -rv -- rsync://ip6-localhost:7873/alice/ 
receiving incremental file list
drwxr-xr-x             80 2020/04/23 04:40:19 .
-rw-r--r--     14,727,168 2020/04/23 04:40:19 onefile
drwxr-xr-x             80 2020/04/23 04:40:19 bob
-rw-r--r--     28,023,808 2020/04/23 04:40:19 bob/anotherfile
drwxr-xr-x             60 2020/04/23 04:40:19 bob/charlie
-rw-r--r--      7,936,000 2020/04/23 04:40:19 bob/charlie/thirdfile

sent 22 bytes  received 163 bytes  370.00 bytes/sec
total size is 50,686,976  speedup is 273,983.65
$ 
Пример файла протокола сервера Rsync.
2020/04/23 08:47:58 [10399] forward name lookup for users.example.com failed: ai_family not supported
2020/04/23 08:47:58 [10399] connect from UNKNOWN (localhost)
2020/04/23 08:48:55 [10498] rsyncd version 3.1.3 starting, listening on port 7873
2020/04/23 08:48:57 [10502] connect from localhost (::1)
2020/04/23 08:48:57 [10502] rsync on alice/ from localhost (::1)
2020/04/23 08:48:57 [10502] building file list
2020/04/23 08:48:57 [10502] sent 184 bytes  received 27 bytes  total size 50686976

Управление серверами при запуске и завершении работы системы

FIXME: раздел в разработке.

Домашнее задание

Для проверки владения материалом по теме лекции на обычном месте будет размещен тест; контрольный срок сдачи — .