return key_list_str.split("\n") if key_list_str else []
+ def get_meta_of_fs_file(self, dir_ino, obj_name, out):
+ """
+ get metadata from parent to verify the correctness of the data format encoded by the tool, cephfs-meta-injection.
+ warning : The splitting of directory is not considered here.
+ """
+ dirfrag_obj_name = "{0:x}.00000000".format(dir_ino)
+ try:
+ ret = self.rados(["getomapval", dirfrag_obj_name, obj_name+"_head", out])
+ except CommandFailedError as e:
+ log.error(e.__str__())
+ raise ObjectNotFound(dir_ino)
+
def erase_metadata_objects(self, prefix):
"""
For all objects in the metadata pool matching the prefix,
fs_rank = self._make_rank(rank)
return self._run_tool("cephfs-journal-tool", args, fs_rank, quiet)
+ def meta_tool(self, args, rank, quiet=False):
+ """
+ Invoke cephfs-meta-injection with the passed arguments for a rank, and return its stdout
+ """
+ fs_rank = self._make_rank(rank)
+ return self._run_tool("cephfs-meta-injection", args, fs_rank, quiet)
+
def table_tool(self, args, quiet=False):
"""
Invoke cephfs-table-tool with the passed arguments, and return its stdout
--- /dev/null
+from tasks.cephfs.cephfs_test_case import CephFSTestCase
+import random
+import os
+
+class TestMetaInjection(CephFSTestCase):
+ def test_meta_injection(self):
+ conf_ori = self.fs.mds_asok(['config', 'show'])
+ self.fs.mds_asok(['config', 'set', 'mds_log_max_segments', '1'])
+ self.mount_a.run_shell(["mkdir", "metadir"])
+ self.mount_a.run_shell(["touch", "metadir/metafile1"])
+ self.mount_a.run_shell(["touch", "metadir/metafile2"])
+ self.fs.mds_asok(['flush', 'journal'])
+ dirino = self.mount_a.path_to_ino("metadir")
+ ino = self.mount_a.path_to_ino("metadir/metafile1")
+
+ # export meta of ino
+ self.fs.meta_tool(['showm', '-i', str(ino), '-o', '/tmp/meta_out'], 0, True)
+ out = self.mount_a.run_shell(['grep', str(ino),'/tmp/meta_out']).stdout.getvalue().strip()
+
+ # check the metadata of ino
+ self.assertNotEqual(out.find(u'"ino":'+ str(ino)), -1)
+
+ # amend info of ino
+ self.fs.get_meta_of_fs_file(dirino, "metafile1", "/tmp/meta_obj")
+ self.fs.meta_tool(['amend', '-i', str(ino), '--in', '/tmp/meta_out', '--yes-i-really-really-mean-it'], 0, True)
+ self.fs.get_meta_of_fs_file(dirino, "metafile1", "/tmp/meta_obj_chg")
+
+ # checkout meta_out after import it
+ ori_mds5 = self.mount_a.run_shell(["md5sum", "/tmp/meta_obj"]).stdout.getvalue().strip().split()
+ chg_mds5 = self.mount_a.run_shell(["md5sum", "/tmp/meta_obj_chg"]).stdout.getvalue().strip().split()
+ print ori_mds5," ==> ", chg_mds5
+ self.assertEqual(len(ori_mds5), 2)
+ self.assertEqual(len(chg_mds5), 2)
+ self.assertEqual(ori_mds5[0], chg_mds5[0])
+
+ self.mount_a.run_shell(["rm", "metadir", "-rf"])
+ self.mount_a.run_shell(["rm", "/tmp/meta_obj"])
+ self.mount_a.run_shell(["rm", "/tmp/meta_obj_chg"])
+ # restore config of mds_log_max_segments
+ self.fs.mds_asok(['config', 'set', 'mds_log_max_segments', conf_ori["mds_log_max_segments"]])
# Help developers by stopping up-front if their tree isn't built enough for all the
# tools that the tests might want to use (add more here if needed)
require_binaries = ["ceph-dencoder", "cephfs-journal-tool", "cephfs-data-scan",
- "cephfs-table-tool", "ceph-fuse", "rados"]
+ "cephfs-table-tool", "ceph-fuse", "rados", "cephfs-meta-injection"]
missing_binaries = [b for b in require_binaries if not os.path.exists(os.path.join(BIN_PREFIX, b))]
if missing_binaries and not opt_ignore_missing_binaries:
log.error("Some ceph binaries missing, please build them: {0}".format(" ".join(missing_binaries)))
for (auto role : role_selector.get_roles()) {
rank = role.rank;
- int ret = process(mode, ino, out, in, confirm);
- cout << "executing for rank " << rank << " op[" <<mode<< "] ret : " << ret << std::endl;
+ r = process(mode, ino, out, in, confirm);
+ cout << "executing for rank " << rank << " op[" <<mode<< "] ret : " << r << std::endl;
}
}else{
rank = conv_t<int>(manual_rank_num);
- int ret = process(mode, ino, out, in, confirm);
- cout << "op[" << mode << "] ret : " << ret << std::endl;
+ r = process(mode, ino, out, in, confirm);
+ cout << "op[" << mode << "] ret : " << r << std::endl;
}
return r;
}
<< " You must confirm that all logs of mds have been flushed!!!\n"
<< " if you want amend it, please add --yes-i-really-really-mean-it!!!"
<< std::endl;
-
+ return -1;
}
bufferlist bl;
inode_meta.encode(bl, features);
to_set[k].swap(bl);
inode_backpointer_t bp;
if (!op.top_op()->get_ancestor(bp))
- return false;
+ return -1;
frag_t frag;
auto item = op.inodes.find(bp.dirino);
if (item != op.inodes.end()){
all.add(modeoptions).add(general);
po::variables_map vm;
try{
- po::store(po::command_line_parser(argc, argv).options(all).positional(p).run(), vm);
+ po::store(po::command_line_parser(argc, argv).options(all).positional(p).allow_unregistered().run(), vm);
}catch(exception &e){
cerr << "error : " << e.what() << std::endl;
return -1;