Skip to content

Commit 6185d08

Browse files
committed
Merge PR ceph#54485 into main
* refs/pull/54485/head: mds/quiesce-db: keep the db thread alive until shutdown mds/quiesce-db: incorporate review comments mds/quiesce: declare QuiesceDbPeerListing and QuiesceDbPeerAck mds/quiesce: resolve the quiesce cluster at the mds monitor include/types: add an I/O helper for std::unordered_map messages: avoid using mutable members in MMDSQuiesce* mds/quiesce-db: incorporate review comments doc/cephfs/fs-volumes: doc fixes and updates pybind/mgr: correct type hints for `get_quiesce_leader_info` mds/quiesce: only use ACTIVE daemons for the quiesce cluster mds,messages: quiesce db inter-rank messaging mds/quiesce: MDSRankQuiesce - integration of the quiesce db manager doc/cephfs/fs-volumes: Add info about the quiesce command doc: fixes for local dev builds mgr/volumes: support for `fs subvolume quiesce` mgr/volumes: use `volume_exception_to_retval` as a decorator pybind/mgr: add a `one-shot` parameter to send_command mds/quiesce: QuiesceAgent implementation and unit tests mds/quiesce: QuiesceDb.h and QuiesceDbManager with tests common/Timer.cc: improve debug messages from the timer_thread mds: MDSRank.cc: return status from `send_message_mds` encoding: add emplace variants for map dencoders common/Cond: make C_SaferCond private members protected to facilitate inheritance qa/tasks/cephfs: give the tests more time to run heavy fs workloads Reviewed-by: Venky Shankar <[email protected]> Reviewed-by: Patrick Donnelly <[email protected]>
2 parents e08c812 + 8b896a9 commit 6185d08

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+6963
-60
lines changed

doc/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/overview.png
22
/object_store.png
3+
_build/

doc/_ext/ceph_commands.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def parse_cmd(cmd):
177177

178178
@staticmethod
179179
def parse_args(args):
180-
return [Sig._parse_arg_desc(arg) for arg in args.split()]
180+
return [Sig._parse_arg_desc(arg) for arg in args]
181181

182182

183183
TEMPLATE = '''
@@ -358,8 +358,9 @@ def run(self):
358358
cmds = sorted(cmds, key=lambda cmd: cmd.prefix)
359359
self._render_cmds(cmds)
360360

361-
orig_rgw_mod = sys.modules['pybind_rgw_mod']
362-
sys.modules['rgw'] = orig_rgw_mod
361+
if 'pybind_rgw_mod' in sys.modules:
362+
orig_rgw_mod = sys.modules['pybind_rgw_mod']
363+
sys.modules['rgw'] = orig_rgw_mod
363364

364365
return []
365366

doc/cephfs/fs-volumes.rst

Lines changed: 375 additions & 2 deletions
Large diffs are not rendered by default.

doc/cephfs/quiesce-set-states.svg

Lines changed: 142 additions & 0 deletions
Loading

doc/conf.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@
1313
os.path.dirname(
1414
os.path.abspath(__file__)))
1515

16-
pybind_rgw_mod = __import__('rgw', globals(), locals(), [], 0)
17-
sys.modules['pybind_rgw_mod'] = pybind_rgw_mod
18-
16+
# it could be that ceph was built without RGW support
17+
# e.g. in a local development environment
18+
try:
19+
pybind_rgw_mod = __import__('rgw', globals(), locals(), [], 0)
20+
sys.modules['pybind_rgw_mod'] = pybind_rgw_mod
21+
except Exception:
22+
pass
1923

2024
def parse_ceph_release():
2125
with open(os.path.join(top_level, 'src/ceph_release')) as f:

qa/tasks/cephfs/mount.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -761,17 +761,18 @@ def create_destroy(self):
761761
'rm', '-f', os.path.join(self.hostfs_mntpt, filename)
762762
])
763763

764-
def _run_python(self, pyscript, py_version='python3', sudo=False):
764+
def _run_python(self, pyscript, py_version='python3', sudo=False, timeout=None):
765765
args, omit_sudo = [], True
766766
if sudo:
767767
args.append('sudo')
768768
omit_sudo = False
769-
args += ['stdin-killer', '--', py_version, '-c', pyscript]
769+
timeout_args = ['--timeout', "%d" % timeout] if timeout is not None else []
770+
args += ['stdin-killer', *timeout_args, '--', py_version, '-c', pyscript]
770771
return self.client_remote.run(args=args, wait=False, stdin=run.PIPE,
771772
stdout=StringIO(), omit_sudo=omit_sudo)
772773

773-
def run_python(self, pyscript, py_version='python3', sudo=False):
774-
p = self._run_python(pyscript, py_version, sudo=sudo)
774+
def run_python(self, pyscript, py_version='python3', sudo=False, timeout=None):
775+
p = self._run_python(pyscript, py_version, sudo=sudo, timeout=timeout)
775776
p.wait()
776777
return p.stdout.getvalue().strip()
777778

@@ -1243,7 +1244,7 @@ def write_test_pattern(self, filename, size):
12431244
size=size
12441245
)))
12451246

1246-
def validate_test_pattern(self, filename, size):
1247+
def validate_test_pattern(self, filename, size, timeout=None):
12471248
log.info("Validating {0} bytes from {1}".format(size, filename))
12481249
# Use sudo because cephfs-data-scan may recreate the file with owner==root
12491250
return self.run_python(dedent("""
@@ -1262,7 +1263,7 @@ def validate_test_pattern(self, filename, size):
12621263
""".format(
12631264
path=os.path.join(self.hostfs_mntpt, filename),
12641265
size=size
1265-
)), sudo=True)
1266+
)), sudo=True, timeout=timeout)
12661267

12671268
def open_n_background(self, fs_path, count):
12681269
"""

qa/tasks/cephfs/test_snapshots.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ def test_multimds_mksnap(self):
376376
self.mount_a.write_test_pattern("d0/d1/file_a", 8 * 1024 * 1024)
377377
self.mount_a.run_shell(["mkdir", "d0/.snap/s1"])
378378
self.mount_a.run_shell(["rm", "-f", "d0/d1/file_a"])
379-
self.mount_a.validate_test_pattern("d0/.snap/s1/d1/file_a", 8 * 1024 * 1024)
379+
self.mount_a.validate_test_pattern("d0/.snap/s1/d1/file_a", 8 * 1024 * 1024, timeout=20)
380380

381381
self.mount_a.run_shell(["rmdir", "d0/.snap/s1"])
382382
self.mount_a.run_shell(["rm", "-rf", "d0"])

qa/tasks/mgr/dashboard/test_health.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ class HealthTest(DashboardTestCase):
6363
'balance_automate': bool,
6464
}),
6565
'ever_allowed_features': int,
66-
'root': int
66+
'root': int,
67+
'qdb_leader': int,
68+
'qdb_cluster': JList(int)
6769
})
6870

6971
def test_minimal_health(self):

src/client/Client.cc

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3028,15 +3028,10 @@ void Client::handle_fs_map_user(const MConstRef<MFSMapUser>& m)
30283028
// Cancel all the commands for missing or laggy GIDs
30293029
void Client::cancel_commands(const MDSMap& newmap)
30303030
{
3031-
std::vector<ceph_tid_t> cancel_ops;
3032-
3033-
std::scoped_lock cmd_lock(command_lock);
3034-
auto &commands = command_table.get_commands();
3035-
for (const auto &[tid, op] : commands) {
3031+
cancel_commands_if([=, this](MDSCommandOp const& op) {
30363032
const mds_gid_t op_mds_gid = op.mds_gid;
30373033
if (newmap.is_dne_gid(op_mds_gid) || newmap.is_laggy_gid(op_mds_gid)) {
3038-
ldout(cct, 1) << __func__ << ": cancelling command op " << tid << dendl;
3039-
cancel_ops.push_back(tid);
3034+
ldout(cct, 1) << "cancel_commands: cancelling command op " << op.tid << dendl;
30403035
if (op.outs) {
30413036
std::ostringstream ss;
30423037
ss << "MDS " << op_mds_gid << " went away";
@@ -3048,13 +3043,10 @@ void Client::cancel_commands(const MDSMap& newmap)
30483043
* has its own lock.
30493044
*/
30503045
op.con->mark_down();
3051-
if (op.on_finish)
3052-
op.on_finish->complete(-CEPHFS_ETIMEDOUT);
3046+
return -CEPHFS_ETIMEDOUT;
30533047
}
3054-
}
3055-
3056-
for (const auto &tid : cancel_ops)
3057-
command_table.erase(tid);
3048+
return 0;
3049+
});
30583050
}
30593051

30603052
void Client::handle_mds_map(const MConstRef<MMDSMap>& m)
@@ -6416,7 +6408,8 @@ int Client::mds_command(
64166408
const bufferlist& inbl,
64176409
bufferlist *outbl,
64186410
string *outs,
6419-
Context *onfinish)
6411+
Context *onfinish,
6412+
bool one_shot)
64206413
{
64216414
RWRef_t iref_reader(initialize_state, CLIENT_INITIALIZED);
64226415
if (!iref_reader.is_state_satisfied())
@@ -6475,6 +6468,9 @@ int Client::mds_command(
64756468

64766469
// Open a connection to the target MDS
64776470
ConnectionRef conn = messenger->connect_to_mds(info.get_addrs());
6471+
if (one_shot) {
6472+
conn->send_keepalive();
6473+
}
64786474

64796475
cl.unlock();
64806476
{
@@ -6489,6 +6485,7 @@ int Client::mds_command(
64896485
op.inbl = inbl;
64906486
op.mds_gid = target_gid;
64916487
op.con = conn;
6488+
op.one_shot = one_shot;
64926489

64936490
ldout(cct, 4) << __func__ << ": new command op to " << target_gid
64946491
<< " tid=" << op.tid << " multi_id=" << op.multi_target_id << " "<< cmd << dendl;
@@ -16682,13 +16679,41 @@ void Client::ms_handle_connect(Connection *con)
1668216679
bool Client::ms_handle_reset(Connection *con)
1668316680
{
1668416681
ldout(cct, 0) << __func__ << " on " << con->get_peer_addr() << dendl;
16682+
16683+
cancel_commands_if([=, this](MDSCommandOp const& op) {
16684+
if (op.one_shot && op.con.get() == con) {
16685+
ldout(cct, 1) << "ms_handle_reset: aborting one-shot command op " << op.tid << dendl;
16686+
if (op.outs) {
16687+
std::ostringstream ss;
16688+
ss << "MDS connection reset";
16689+
*(op.outs) = ss.str();
16690+
}
16691+
return -EPIPE;
16692+
}
16693+
return 0;
16694+
});
16695+
1668516696
return false;
1668616697
}
1668716698

1668816699
void Client::ms_handle_remote_reset(Connection *con)
1668916700
{
16690-
std::scoped_lock lock(client_lock);
1669116701
ldout(cct, 0) << __func__ << " on " << con->get_peer_addr() << dendl;
16702+
16703+
cancel_commands_if([=, this](MDSCommandOp const& op) {
16704+
if (op.one_shot && op.con.get() == con) {
16705+
ldout(cct, 1) << "ms_handle_remote_reset: aborting one-shot command op " << op.tid << dendl;
16706+
if (op.outs) {
16707+
std::ostringstream ss;
16708+
ss << "MDS remote session reset";
16709+
*(op.outs) = ss.str();
16710+
}
16711+
return -EPIPE;
16712+
}
16713+
return 0;
16714+
});
16715+
16716+
std::scoped_lock lock(client_lock);
1669216717
switch (con->get_peer_type()) {
1669316718
case CEPH_ENTITY_TYPE_MDS:
1669416719
{
@@ -16747,6 +16772,20 @@ void Client::ms_handle_remote_reset(Connection *con)
1674716772
bool Client::ms_handle_refused(Connection *con)
1674816773
{
1674916774
ldout(cct, 1) << __func__ << " on " << con->get_peer_addr() << dendl;
16775+
16776+
cancel_commands_if([=, this](MDSCommandOp const& op) {
16777+
if (op.one_shot && op.con.get() == con) {
16778+
ldout(cct, 1) << "ms_handle_refused: aborting one-shot command op " << op.tid << dendl;
16779+
if (op.outs) {
16780+
std::ostringstream ss;
16781+
ss << "MDS connection refused";
16782+
*(op.outs) = ss.str();
16783+
}
16784+
return -EPIPE;
16785+
}
16786+
return 0;
16787+
});
16788+
1675016789
return false;
1675116790
}
1675216791

src/client/Client.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class MDSCommandOp : public CommandOp
9696
{
9797
public:
9898
mds_gid_t mds_gid;
99+
bool one_shot = false;
99100

100101
explicit MDSCommandOp(ceph_tid_t t) : CommandOp(t) {}
101102
explicit MDSCommandOp(ceph_tid_t t, ceph_tid_t multi_id) : CommandOp(t, multi_id) {}
@@ -335,7 +336,7 @@ class Client : public Dispatcher, public md_config_obs_t {
335336
const std::string &mds_spec,
336337
const std::vector<std::string>& cmd,
337338
const bufferlist& inbl,
338-
bufferlist *poutbl, std::string *prs, Context *onfinish);
339+
bufferlist *poutbl, std::string *prs, Context *onfinish, bool one_shot = false);
339340

340341
// these should (more or less) mirror the actual system calls.
341342
int statfs(const char *path, struct statvfs *stbuf, const UserPerm& perms);
@@ -714,6 +715,27 @@ class Client : public Dispatcher, public md_config_obs_t {
714715
virtual void shutdown();
715716

716717
// messaging
718+
int cancel_commands_if(std::regular_invocable<MDSCommandOp const&> auto && error_for_op)
719+
{
720+
std::vector<ceph_tid_t> cancel_ops;
721+
722+
std::scoped_lock cmd_lock(command_lock);
723+
auto& commands = command_table.get_commands();
724+
for (const auto &[tid, op]: commands) {
725+
int rc = static_cast<int>(error_for_op(op));
726+
if (rc) {
727+
cancel_ops.push_back(tid);
728+
if (op.on_finish)
729+
op.on_finish->complete(rc);
730+
}
731+
}
732+
733+
for (const auto& tid : cancel_ops)
734+
command_table.erase(tid);
735+
736+
return cancel_ops.size();
737+
}
738+
717739
void cancel_commands(const MDSMap& newmap);
718740
void handle_mds_map(const MConstRef<MMDSMap>& m);
719741
void handle_fs_map(const MConstRef<MFSMap>& m);

0 commit comments

Comments
 (0)