为什么 bareos bpipe 作业会失败,并出现:致命错误:bpipe-fd:管道读取错误:ERR=Error 0

为什么 bareos bpipe 作业会失败,并出现:致命错误:bpipe-fd:管道读取错误:ERR=Error 0

使用 bpipe 插件与 Bareos Backup 时出现错误:

致命错误:bpipe-fd:管道读取错误:ERR=Error 0

zfs send -R dpool/some_dataset

已完成,从 bash 脚本执行。
但只有当且仅当 dpool/some_dataset 有子数据集时(例如有 dpool/some_dataset/child1)。-R 选项在 zfs 发送中包含子数据集。这是我的脚本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 源编译而来。

答案1

显然,我通过搜索找到了解决问题的方法如何在 bash 中回显 EOF?

由于某些不为人知的原因zfs_create_send_snapshot.sh脚本终止它的标准输出的方式有所不同,这取决于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}

顺便说一句:有人可以指出这个奇怪的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()?只是猜测……

相关内容