QUIESCE_HOOK=${TEMPDIR}/quiesce.sh
DEV=`_sudo rbd-nbd map --quiesce --quiesce-hook ${QUIESCE_HOOK} ${POOL}/${IMAGE}`
-# test it does not fail if the hook does not exists
+# test it fails if the hook does not exists
test ! -e ${QUIESCE_HOOK}
-rbd snap create ${POOL}/${IMAGE}@quiesce1
+expect_false rbd snap create ${POOL}/${IMAGE}@quiesce1
_sudo dd if=${DATA} of=${DEV} bs=1M count=1 oflag=direct
# test the hook is executed
echo "test the hook is executed" >&2
echo \$1 > ${TEMPDIR}/\$2
EOF
-rbd snap create ${POOL}/${IMAGE}@quiesce2
+rbd snap create ${POOL}/${IMAGE}@quiesce1
_sudo dd if=${DATA} of=${DEV} bs=1M count=1 oflag=direct
test "$(cat ${TEMPDIR}/quiesce)" = ${DEV}
test "$(cat ${TEMPDIR}/unquiesce)" = ${DEV}
-# test it does not fail if the hook fails
+# test snap create fails if the hook fails
touch ${QUIESCE_HOOK}
chmod +x ${QUIESCE_HOOK}
cat > ${QUIESCE_HOOK} <<EOF
#/bin/sh
-echo "test it does not fail if the hook fails" >&2
-exit 1
+echo "test snap create fails if the hook fails" >&2
+exit 22
EOF
-rbd snap create ${POOL}/${IMAGE}@quiesce3
+expect_false rbd snap create ${POOL}/${IMAGE}@quiesce2
_sudo dd if=${DATA} of=${DEV} bs=1M count=1 oflag=direct
# test the hook is slow
echo "test the hook is slow" >&2
sleep 7
EOF
-rbd snap create ${POOL}/${IMAGE}@quiesce4
+rbd snap create ${POOL}/${IMAGE}@quiesce2
_sudo dd if=${DATA} of=${DEV} bs=1M count=1 oflag=direct
# test rbd-nbd_quiesce hook that comes with distribution
_sudo mkfs ${DEV}
mkdir ${TEMPDIR}/mnt
_sudo mount ${DEV} ${TEMPDIR}/mnt
-rbd snap create ${POOL}/${IMAGE}@quiesce5
+rbd snap create ${POOL}/${IMAGE}@quiesce3
_sudo dd if=${DATA} of=${TEMPDIR}/mnt/test bs=1M count=1 oflag=direct
_sudo umount ${TEMPDIR}/mnt
unmap_device ${DEV}
Command *command, Config *cfg);
static int netlink_resize(int nbd_index, uint64_t size);
-static void run_quiesce_hook(const std::string &quiesce_hook,
- const std::string &devpath,
- const std::string &command);
+static int run_quiesce_hook(const std::string &quiesce_hook,
+ const std::string &devpath,
+ const std::string &command);
class NBDServer
{
while (wait_quiesce()) {
- run_quiesce_hook(cfg->quiesce_hook, cfg->devpath, "quiesce");
+ int r = run_quiesce_hook(cfg->quiesce_hook, cfg->devpath, "quiesce");
wait_inflight_io();
{
std::unique_lock locker{lock};
+ ceph_assert(quiesce == true);
- // TODO: return quiesce hook exit code
- image.quiesce_complete(quiesce_watch_handle, 0);
+ image.quiesce_complete(quiesce_watch_handle, r);
+
+ if (r < 0) {
+ quiesce = false;
+ continue;
+ }
wait_unquiesce(locker);
}
return 0;
}
-static void run_quiesce_hook(const std::string &quiesce_hook,
- const std::string &devpath,
- const std::string &command) {
+static int run_quiesce_hook(const std::string &quiesce_hook,
+ const std::string &devpath,
+ const std::string &command) {
dout(10) << __func__ << ": " << quiesce_hook << " " << devpath << " "
<< command << dendl;
hook.add_cmd_args(devpath.c_str(), command.c_str(), NULL);
bufferlist err;
int r = hook.spawn();
- if (r != 0) {
+ if (r < 0) {
err.append("subprocess spawn failed");
} else {
err.read_fd(hook.get_stderr(), 16384);
r = hook.join();
+ if (r > 0) {
+ r = -r;
+ }
}
- if (r != 0) {
+ if (r < 0) {
derr << __func__ << ": " << quiesce_hook << " " << devpath << " "
<< command << " failed: " << err.to_str() << dendl;
} else {
dout(10) << " succeeded: " << err.to_str() << dendl;
}
+
+ return r;
}
static void handle_signal(int signum)