Назад | Перейти на главную страницу

Почему задание bareos bpipe завершается с ошибкой: Неустранимая ошибка: bpipe-fd: Ошибка чтения трубы: ERR = Ошибка 0

Используя плагин bpipe с Bareos Backup, я получаю сообщение об ошибке:

Неустранимая ошибка: bpipe-fd: ошибка чтения трубы: ERR = Ошибка 0

после

zfs send -R dpool/some_dataset

завершено, выполняется из сценария bash.
Но только если dpool / some_dataset имеет дочерние наборы данных (например, dpool / some_dataset / child1). Параметр -R включает дочерний элемент в zfs send. Это мой сценарий zfs_create_send_snapshot.sh:

#!/bin/sh
#
# create recursive ZFS snapshot for given dataset and pipe
# replication stream to stdout, then delete snapshot

if [ -z "$1" ]; then
  (>&2 echo "ERROR: missing dataset name argument")
  exit 1
fi

DDD=`date +%y%m%d%H%M`
SNAPNAME=$1@bareos_${DDD}
(>&2 echo "creating ZFS snapshot ${SNAPNAME}")

zfs snapshot -r ${SNAPNAME}
(>&2 echo "sending ZFS snapshot ${SNAPNAME}")
zfs send -R ${SNAPNAME}
RC=$?
(>&2 echo "deleting ZFS snapshot ${SNAPNAME}")
(>&2 zfs destroy -r ${SNAPNAME})
exit ${RC}

Он выполняется набором файлов bareos следующим образом:

Plugin = "bpipe:file=/tmp/zfs_snap.bin:reader=/etc/bareos zfs_create_send_snapshot.sh dpool/some_dataset:writer=/etc/bareos/writer.sh /tmp/zfs_snap.bin"

Задание не выполняется с ошибкой разрыва канала, только если dpool / some_dataset имеет дочерние наборы данных zfs. В остальном все нормально. И, похоже, это всего лишь побочный эффект: задание резервного копирования записывает полный поток моментальных снимков zfs на ленту до тех пор, пока ... просто ошибочно завершится из-за ошибки. Такое бывает на openindiana / illumos. Последний клиент Bareos 17.2 скомпилирован из исходников git.

Очевидно, я нашел способ решения проблемы / ошибки, выполнив поиск Как отобразить EOF в bash?

По какой-то непонятной причине zfs_create_send_snapshot.sh сценарий завершает его stdout как-то иначе, в зависимости от того, zfs отправить отправляет более одной файловой системы ... Очень странно.

Итак, добавив exec 1>&- после zfs send внутри скрипта решает проблему.

#!/bin/sh
#
# create recursive ZFS snapshot for given dataset and pipe
# replication stream to stdout, then delete snapshot

if [ -z "$1" ]; then
  (>&2 echo "ERROR: missing dataset name argument")
  exit 1
fi

DDD=`date +%y%m%d%H%M`
SNAPNAME=$1@bareos_${DDD}
(>&2 echo "creating ZFS snapshot ${SNAPNAME}")

zfs snapshot -r ${SNAPNAME}
(>&2 echo "sending ZFS snapshot ${SNAPNAME}")
zfs send -R ${SNAPNAME}
RC=$?
exec 1>&-
(>&2 echo "deleting ZFS snapshot ${SNAPNAME}")
(>&2 zfs destroy -r ${SNAPNAME})
exit ${RC}

Кстати: может кто-нибудь указать мне на хорошую ссылку на этот stange exec 1 >&- синтаксис / команда !?

В поисках первопричины я обнаружил этот фрагмент кода в источниках bareos fd (bareos / core / src / plugins / filed / bpipe-fd.cc):

   case IO_READ:
      if (!p_ctx->pfd) {
        Jmsg(ctx, M_FATAL, "bpipe-fd: Logic error: NULL read FD\n");
        Dmsg(ctx, debuglevel, "bpipe-fd: Logic error: NULL read FD\n");
        return bRC_Error;
      }
      io->status = fread(io->buf, 1, io->count, p_ctx->pfd->rfd);
      if (io->status == 0 && ferror(p_ctx->pfd->rfd)) {
        io->io_errno = errno;
        Jmsg(ctx, M_FATAL, "bpipe-fd: Pipe read error: ERR=%s\n",
             strerror(io->io_errno));
        Dmsg(ctx, debuglevel, "bpipe-fd: Pipe read error: ERR=%s\n",
             strerror(io->io_errno));
        return bRC_Error;
      }
      break;

Возможно, отсутствует feof ()? Просто предположение...