Skip to content

Commit 1e1258d

Browse files
authored
Merge branch 'ceph:main' into main
2 parents 947b5d2 + 8a7e670 commit 1e1258d

File tree

15 files changed

+270
-40
lines changed

15 files changed

+270
-40
lines changed

qa/tasks/cephfs/test_exports.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from tasks.cephfs.fuse_mount import FuseMount
55
from tasks.cephfs.cephfs_test_case import CephFSTestCase
66
from teuthology.exceptions import CommandFailedError
7+
from teuthology.contextutil import safe_while, MaxWhileTries
78

89
log = logging.getLogger(__name__)
910

@@ -628,3 +629,98 @@ def test_ephemeral_pin_shrink_mds(self):
628629
log.info("{0} migrations have occured due to the cluster resizing".format(count))
629630
# rebalancing from 3 -> 2 may cause half of rank 0/1 to move and all of rank 2
630631
self.assertLessEqual((count/len(subtrees_old)), (1.0/3.0/2.0 + 1.0/3.0/2.0 + 1.0/3.0)*1.25) # aka .66 with 25% overbudget
632+
633+
class TestDumpExportStates(CephFSTestCase):
634+
MDSS_REQUIRED = 2
635+
CLIENTS_REQUIRED = 1
636+
637+
EXPORT_STATES = ['locking', 'discovering', 'freezing', 'prepping', 'warning', 'exporting']
638+
639+
def setUp(self):
640+
super().setUp()
641+
642+
self.fs.set_max_mds(self.MDSS_REQUIRED)
643+
self.status = self.fs.wait_for_daemons()
644+
645+
self.mount_a.run_shell_payload('mkdir -p test/export')
646+
647+
def tearDown(self):
648+
super().tearDown()
649+
650+
def _wait_for_export_target(self, source, target, sleep=2, timeout=10):
651+
try:
652+
with safe_while(sleep=sleep, tries=timeout//sleep) as proceed:
653+
while proceed():
654+
info = self.fs.getinfo().get_rank(self.fs.id, source)
655+
log.info(f'waiting for rank {target} to be added to the export target')
656+
if target in info['export_targets']:
657+
return
658+
except MaxWhileTries as e:
659+
raise RuntimeError(f'rank {target} has not been added to export target after {timeout}s') from e
660+
661+
def _dump_export_state(self, rank):
662+
states = self.fs.rank_asok(['dump_export_states'], rank=rank, status=self.status)
663+
self.assertTrue(type(states) is list)
664+
self.assertEqual(len(states), 1)
665+
return states[0]
666+
667+
def _test_base(self, path, source, target, state_index, kill):
668+
self.fs.rank_asok(['config', 'set', 'mds_kill_import_at', str(kill)], rank=target, status=self.status)
669+
670+
self.fs.rank_asok(['export', 'dir', path, str(target)], rank=source, status=self.status)
671+
self._wait_for_export_target(source, target)
672+
673+
target_rank = self.fs.get_rank(rank=target, status=self.status)
674+
self.delete_mds_coredump(target_rank['name'])
675+
676+
state = self._dump_export_state(source)
677+
678+
self.assertTrue(type(state['tid']) is int)
679+
self.assertEqual(state['path'], path)
680+
self.assertEqual(state['state'], self.EXPORT_STATES[state_index])
681+
self.assertEqual(state['peer'], target)
682+
683+
return state
684+
685+
def _test_state_history(self, state):
686+
history = state['state_history']
687+
self.assertTrue(type(history) is dict)
688+
size = 0
689+
for name in self.EXPORT_STATES:
690+
self.assertTrue(type(history[name]) is dict)
691+
size += 1
692+
if name == state['state']:
693+
break
694+
self.assertEqual(len(history), size)
695+
696+
def _test_freeze_tree(self, state, waiters):
697+
self.assertTrue(type(state['freeze_tree_time']) is float)
698+
self.assertEqual(state['unfreeze_tree_waiters'], waiters)
699+
700+
def test_discovering(self):
701+
state = self._test_base('/test', 0, 1, 1, 1)
702+
703+
self._test_state_history(state)
704+
self._test_freeze_tree(state, 0)
705+
706+
self.assertEqual(state['last_cum_auth_pins'], 0)
707+
self.assertEqual(state['num_remote_waiters'], 0)
708+
709+
def test_prepping(self):
710+
client_id = self.mount_a.get_global_id()
711+
712+
state = self._test_base('/test', 0, 1, 3, 3)
713+
714+
self._test_state_history(state)
715+
self._test_freeze_tree(state, 0)
716+
717+
self.assertEqual(state['flushed_clients'], [client_id])
718+
self.assertTrue(type(state['warning_ack_waiting']) is list)
719+
720+
def test_exporting(self):
721+
state = self._test_base('/test', 0, 1, 5, 5)
722+
723+
self._test_state_history(state)
724+
self._test_freeze_tree(state, 0)
725+
726+
self.assertTrue(type(state['notify_ack_waiting']) is list)

qa/workunits/fs/snaps/snaptest-git-ceph.sh

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ set -e
44

55
# increase the cache size
66
sudo git config --global http.sslVerify false
7-
sudo git config --global http.postBuffer 1048576000
7+
sudo git config --global http.postBuffer 1024MB # default is 1MB
8+
sudo git config --global http.maxRequestBuffer 100M # default is 10MB
9+
sudo git config --global core.compression 0
10+
11+
# enable the debug logs for git clone
12+
export GIT_TRACE_PACKET=1
13+
export GIT_TRACE=1
14+
export GIT_CURL_VERBOSE=1
815

916
# try it again if the clone is slow and the second time
1017
retried=false
@@ -19,6 +26,11 @@ timeout 1800 git clone https://git.ceph.com/ceph.git
1926
trap - EXIT
2027
cd ceph
2128

29+
# disable the debug logs for git clone
30+
export GIT_TRACE_PACKET=0
31+
export GIT_TRACE=0
32+
export GIT_CURL_VERBOSE=0
33+
2234
versions=`seq 1 90`
2335

2436
for v in $versions

src/mds/CDir.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,16 @@ class CDir : public MDSCacheObject, public Counter<CDir> {
546546

547547
void maybe_finish_freeze();
548548

549+
size_t count_unfreeze_tree_waiters() {
550+
size_t n = count_unfreeze_dir_waiters();
551+
_walk_tree([&n](CDir *dir) {
552+
n += dir->count_unfreeze_dir_waiters();
553+
return true;
554+
});
555+
return n;
556+
}
557+
inline size_t count_unfreeze_dir_waiters() const { return count_waiters(WAIT_UNFREEZE); }
558+
549559
std::pair<bool,bool> is_freezing_or_frozen_tree() const {
550560
if (freeze_tree_state) {
551561
if (freeze_tree_state->frozen)

src/mds/MDSCacheObject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ class MDSCacheObject {
260260
}
261261
bool is_waiter_for(waitmask_t mask);
262262

263+
inline size_t count_waiters(uint64_t mask) const { return waiting.count(mask); }
264+
263265
virtual void add_waiter(uint64_t mask, MDSContext *c) {
264266
add_waiter(waitmask_t(mask), c);
265267
}

src/mds/MDSDaemon.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ void MDSDaemon::set_up_admin_socket()
304304
asok_hook,
305305
"show recent ops, sorted by op duration");
306306
ceph_assert(r == 0);
307+
r = admin_socket->register_command("dump_export_states",
308+
asok_hook,
309+
"dump export states");
310+
ceph_assert(r == 0);
307311
r = admin_socket->register_command("scrub_path name=path,type=CephString "
308312
"name=scrubops,type=CephChoices,"
309313
"strings=force|recursive|repair,n=N,req=false "

src/mds/MDSRank.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,9 @@ void MDSRankDispatcher::handle_asok_command(
27692769
if (!op_tracker.dump_historic_ops(f, true)) {
27702770
*css << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
27712771
}
2772+
} else if (command == "dump_export_states") {
2773+
std::lock_guard l(mds_lock);
2774+
mdcache->migrator->dump_export_states(f);
27722775
} else if (command == "osdmap barrier") {
27732776
int64_t target_epoch = 0;
27742777
bool got_val = cmd_getval(cmdmap, "target_epoch", target_epoch);

0 commit comments

Comments
 (0)