Ошибка ввода-вывода в rsync при ежедневном резервном копировании

Ошибка ввода-вывода в rsync при ежедневном резервном копировании

У меня есть образец сервера NAS (QNAP TS-210) с очень ограниченным набором Linux (хотя и немного усиленным с помощью Optware/IPKG). Я новичок в Linux. Покопавшись в Интернете, я смог написать свой собственный скрипт резервного копирования, используя rsync для синхронизации файлов между жестким диском NAS и внешними USB-накопителями, и CRON для периодического запуска этого скрипта.

Все было хорошо, пока несколько дней назад. Электронные письма, сгенерированные скриптом резервного копирования, не начали содержать информацию IO error encountered -- skipping file deletionо многих ресурсах (папках), которые копируются. Когда я запустил тот же самый скрипт через SSH, я получил много строк с ошибками, в которых говорилось " cannot send file with empty name in...", а затем " rsync error: some files/attrs were not transferred (see previous errors)".

100% контента, который я копирую, поступает из Windows (я использую NAS только для резервного копирования своих компьютеров). Эта система не позволяет создавать файлы с пустым именем. Эта проблема существует всего несколько дней, и я не вносил изменения в свои резервные копии в течение нескольких недель (отпуск). Так что это проблема Linux (на борту моего NAS).

Вопрос: что может вызывать появление файлов с пустыми именами? Как мне избавиться от них (когда я cdперехожу в папку, указанную в отчете rsync, и делаю это ls -ls, я не вижу ничего похожего на "файл с пустым именем"), чтобы следующий проход rsync завершился без таких ошибок. И наконец -- как избежать появления таких файлов в будущем?

решение1

Я не думаю, что это вина rsync. Я думаю, вы правильно отметили это как проблему на уровне ядра, поскольку соответствующий кодflist.cиз источников rsyncчитает:

1729         for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) {
1730                 unsigned name_len;
1731                 char *dname = d_name(di);
...
1746                 if (dname[0] == '\0') {
1747                         io_error |= IOERR_GENERAL;
1748                         rprintf(FERROR_XFER,
1749                                 "cannot send file with empty name in %s\n",
1750                                 full_fname(fbuf));

На самом деле эта строка кода была добавлена ​​разработчиком rsyncеще в августе 2007 годаспециально для этого случая:

If readdir() gives us an empty name, reject it.

Другими словами, readdir()сама (функция ядра, которая возвращает список файлов в каталоге) вернула запись с пустой строкой. Согласно правилам, этого никогда не должно происходить. Цитата изСпецификация Open Group:

The readdir() function shall not return directory entries containing empty names.

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

Итак, ответ на ваши вопросы:

  1. Причиной, по-видимому, является повреждение файловой системы. Причиной может быть что угодно: от ошибки драйвера ядра до аппаратного сбоя.Также стоит проверить, доступен ли каталог, к которому вы подключаетесь с помощью rsync, через символическую ссылку или он сам пересекает сетевую границу, в которой могут возникнуть проблемы.

  2. Чтобы от них избавиться: обычный контрольный список восстановления файловой системы: fsck и т. д.

  3. Чтобы избежать этого в будущем: я полагаю, вы могли бы заранее указать своему скрипту принудительно выполнять рекурсивный листинг, но поскольку вас уже заметили (и вы вернулись из отпуска), кажется правильным будет следить за этим и немедленно реагировать, если это повторится.

Надеюсь, это было полезно, удачи!

Связанный контент