Skip to content

Commit fd88b52

Browse files
committed
mds/quiesce: db: quiesce-await should EPERM if a set is past QS_QUIESCED
Fixes: https://tracker.ceph.com/issues/65669 Signed-off-by: Leonid Usov <[email protected]>
1 parent dcce768 commit fd88b52

File tree

3 files changed

+43
-17
lines changed

3 files changed

+43
-17
lines changed

doc/cephfs/fs-volumes.rst

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,15 +1010,41 @@ Note that the commands above are all non-blocking. If we want to wait for the qu
10101010
to reach the `QUIESCED` state, we should await it at some point. ``--await`` can be given
10111011
along with other arguments to let the system know our intention.
10121012

1013-
Technically, there are two types of await: `quiesce await` and `release await`. The former
1014-
is the default, and the latter can only be achieved with ``--release`` present in the argument list.
1015-
To avoid confision, it is not permitted to issue a `quiesce await` when the set is already `RELEASING`
1016-
or `RELEASED`. Trying to ``--release`` a set that is not `QUIESCED` is an ``EPERM`` error as well, regardless
1017-
of whether await is requested alongside. However, it's not an error to `release await`
1018-
an already released set, or to `quiesce await` a `QUIESCED` one.
1019-
1020-
When awaiting, one may also specify a maximum duration that they would like this await request to block for,
1021-
not affecting the two intrinsic timeouts discussed above. If the target awaited state isn't reached
1013+
There are two types of await: `quiesce await` and `release await`. The former is the default,
1014+
and the latter can only be achieved with ``--release`` present in the argument list.
1015+
To avoid confision, it is not permitted to issue a `quiesce await` when the set is not `QUIESCING`.
1016+
Trying to ``--release`` a set that is not `QUIESCED` is an ``EPERM`` error as well, regardless
1017+
of whether await is requested alongside. However, it's not an error to `release await`
1018+
an already released set, or to `quiesce await` a `QUIESCED` one - those are successful no-ops.
1019+
1020+
Since a set is awaited after the application of the ``--await``-augmented command, the await operation
1021+
may mask a successful result with its own error. A good example is trying to cancel-await a set:
1022+
1023+
.. prompt:: bash $ auto
1024+
1025+
$ ceph fs quiesce fs1 --set-id set1 --cancel --await
1026+
{
1027+
// ...
1028+
"sets": {
1029+
"set1": {
1030+
// ...
1031+
"state": {
1032+
"name": "CANCELED",
1033+
"age": 0
1034+
},
1035+
// ...
1036+
}
1037+
}
1038+
}
1039+
Error EPERM:
1040+
1041+
Although ``--cancel`` will succeed syncrhonously for a set in an active state, awaiting a canceled
1042+
set is not permitted, hence this call will result in an ``EPERM``. This is deliberately different from
1043+
returning a ``EINVAL`` error, denoting an error on the user's side, to simplify the system's behavior
1044+
when ``--await`` is requested. As a result, it's also a simpler model for the user to work with.
1045+
1046+
When awaiting, one may specify a maximum duration that they would like this await request to block for,
1047+
orthogonally to the two intrinsic set timeouts discussed above. If the target awaited state isn't reached
10221048
within the specified duration, then ``EINPROGRESS`` is returned. For that, one should use the argument
10231049
``--await-for=<seconds>``. One could think of ``--await`` as equivalent to ``--await-for=Infinity``.
10241050
While it doesn't make sense to specify both arguments, it is not considered an error. If

src/mds/QuiesceDbManager.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,12 +623,13 @@ int QuiesceDbManager::leader_process_request(RequestContext* req_ctx)
623623
}
624624

625625
if (request.await) {
626+
// quiesce-await is only allowed for sets that are quiescing or quiesced.
626627
// this check may have a false negative for a quiesced set
627628
// that will be released in another request in the same batch
628629
// in that case, this await will be enqueued but then found and completed
629630
// with the same error in `leader_upkeep_awaits`
630-
if ((set.is_releasing() || set.is_released()) && !request.is_release()) {
631-
dout(2) << dset("can't quiesce-await a set that was released (") << set.rstate.state << ")" << dendl;
631+
if (set.rstate.state > QS_QUIESCED && !request.is_release()) {
632+
dout(2) << dset("can't quiesce-await a set in the state: ") << set.rstate.state << dendl;
632633
return EPERM;
633634
}
634635

@@ -1055,7 +1056,7 @@ QuiesceTimeInterval QuiesceDbManager::leader_upkeep_awaits()
10551056
break;
10561057
case QS_EXPIRED:
10571058
case QS_TIMEDOUT:
1058-
rc = ETIMEDOUT;
1059+
rc = ETIMEDOUT;
10591060
break;
10601061
case QS_QUIESCED:
10611062
rc = 0; // fallthrough

src/test/mds/TestQuiesceDb.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,13 +1010,12 @@ TEST_F(QuiesceDbTest, InterruptedQuiesceAwait)
10101010
EXPECT_EQ(ERR(ECANCELED), await3.wait_result());
10111011
EXPECT_EQ(ERR(ECANCELED), await4.wait_result());
10121012

1013-
// awaiting a set in a terminal state should immediately
1014-
// complete with the corresponding error
1015-
ASSERT_EQ(ERR(ECANCELED), run_request([](auto& r) {
1013+
// awaiting a set in a terminal state should be illegal
1014+
EXPECT_EQ(ERR(EPERM), run_request([](auto& r) {
10161015
r.set_id = "set1";
10171016
r.await = sec(100);
10181017
}));
1019-
ASSERT_EQ(ERR(ETIMEDOUT), run_request([](auto& r) {
1018+
EXPECT_EQ(ERR(EPERM), run_request([](auto& r) {
10201019
r.set_id = "set2";
10211020
r.await = sec(100);
10221021
}));
@@ -1082,7 +1081,7 @@ TEST_F(QuiesceDbTest, RepeatedQuiesceAwait) {
10821081

10831082
EXPECT_EQ(QS_EXPIRED, last_request->response.sets.at("set1").rstate.state);
10841083

1085-
EXPECT_EQ(ERR(ETIMEDOUT), run_request([](auto& r) {
1084+
EXPECT_EQ(ERR(EPERM), run_request([](auto& r) {
10861085
r.set_id = "set1";
10871086
r.await = sec(0.1);
10881087
}));

0 commit comments

Comments
 (0)