Используя плагин 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 ()? Просто предположение...