mirror of
https://github.com/ceph/ceph
synced 2025-01-03 09:32:43 +00:00
Complete replacement of ceph_filestore_tool and ceph_filestore_dump
with unified ceph_objectstore_tool Move list-lost-objects and fix-lost-objects features from ceph_filestore_tool to ceph_objectstore_tool as list-lost, fix-lost Change --type to --op for info, log, export...operations Add --type for the ObjectStore type (defaults to filestore) Change --filestore-path to --data-path Update installation, Makefile.am, and .gitignore Fix and rename test case to match Add some additional invalid option checks Signed-off-by: David Zafman <david.zafman@inktank.com>
This commit is contained in:
parent
77864193a1
commit
83fbc91e5c
@ -715,8 +715,7 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
|
||||
%{_bindir}/ceph_smalliobenchdumb
|
||||
%{_bindir}/ceph_smalliobenchfs
|
||||
%{_bindir}/ceph_smalliobenchrbd
|
||||
%{_bindir}/ceph_filestore_dump
|
||||
%{_bindir}/ceph_filestore_tool
|
||||
%{_bindir}/ceph_objectstore_tool
|
||||
%{_bindir}/ceph_streamtest
|
||||
%{_bindir}/ceph_test_*
|
||||
%{_bindir}/ceph_tpbench
|
||||
|
3
debian/ceph-test.install
vendored
3
debian/ceph-test.install
vendored
@ -1,8 +1,7 @@
|
||||
usr/bin/ceph-coverage
|
||||
usr/bin/ceph_bench_log
|
||||
usr/bin/ceph_dupstore
|
||||
usr/bin/ceph_filestore_dump
|
||||
usr/bin/ceph_filestore_tool
|
||||
usr/bin/ceph_objectstore_tool
|
||||
usr/bin/ceph_kvstorebench
|
||||
usr/bin/ceph_multi_stress_watch
|
||||
usr/bin/ceph_erasure_code
|
||||
|
3
src/.gitignore
vendored
3
src/.gitignore
vendored
@ -25,8 +25,7 @@ Makefile
|
||||
/ceph.conf
|
||||
/ceph_bench_log
|
||||
/ceph_dupstore
|
||||
/ceph_filestore_dump
|
||||
/ceph_filestore_tool
|
||||
/ceph_objectstore_tool
|
||||
/ceph_mon_store_converter
|
||||
/ceph_multi_stress_watch
|
||||
/ceph_erasure_code
|
||||
|
@ -139,7 +139,7 @@ def main():
|
||||
pid = os.getpid()
|
||||
TESTDIR = "/tmp/test.{pid}".format(pid=pid)
|
||||
DATADIR = "/tmp/data.{pid}".format(pid=pid)
|
||||
CFSD_PREFIX = "./ceph_filestore_dump --filestore-path dev/{osd} --journal-path dev/{osd}.journal "
|
||||
CFSD_PREFIX = "./ceph_objectstore_tool --data-path dev/{osd} --journal-path dev/{osd}.journal "
|
||||
DATALINECOUNT = 10000
|
||||
PROFNAME = "testecprofile"
|
||||
|
||||
@ -307,7 +307,7 @@ def main():
|
||||
|
||||
print "Test invalid parameters"
|
||||
# On export can't use stdout to a terminal
|
||||
cmd = (CFSD_PREFIX + "--type export --pgid {pg}").format(osd=ONEOSD, pg=ONEPG)
|
||||
cmd = (CFSD_PREFIX + "--op export --pgid {pg}").format(osd=ONEOSD, pg=ONEPG)
|
||||
ERRORS += test_failure(cmd, "stdout is a tty and no --file option specified")
|
||||
|
||||
OTHERFILE = "/tmp/foo.{pid}".format(pid=pid)
|
||||
@ -315,30 +315,42 @@ def main():
|
||||
foofd.close()
|
||||
|
||||
# On import can't specify a PG
|
||||
cmd = (CFSD_PREFIX + "--type import --pgid {pg} --file {FOO}").format(osd=ONEOSD, pg=ONEPG, FOO=OTHERFILE)
|
||||
cmd = (CFSD_PREFIX + "--op import --pgid {pg} --file {FOO}").format(osd=ONEOSD, pg=ONEPG, FOO=OTHERFILE)
|
||||
ERRORS += test_failure(cmd, "--pgid option invalid with import")
|
||||
|
||||
os.unlink(OTHERFILE)
|
||||
cmd = (CFSD_PREFIX + "--type import --file {FOO}").format(osd=ONEOSD, FOO=OTHERFILE)
|
||||
cmd = (CFSD_PREFIX + "--op import --file {FOO}").format(osd=ONEOSD, FOO=OTHERFILE)
|
||||
ERRORS += test_failure(cmd, "open: No such file or directory")
|
||||
|
||||
# On import can't use stdin from a terminal
|
||||
cmd = (CFSD_PREFIX + "--type import --pgid {pg}").format(osd=ONEOSD, pg=ONEPG)
|
||||
cmd = (CFSD_PREFIX + "--op import --pgid {pg}").format(osd=ONEOSD, pg=ONEPG)
|
||||
ERRORS += test_failure(cmd, "stdin is a tty and no --file option specified")
|
||||
|
||||
# Test --type list and generate json for all objects
|
||||
print "Test --type list by generating json for all objects"
|
||||
# Specify a bad --type
|
||||
cmd = (CFSD_PREFIX + "--type foobar --op list --pgid {pg}").format(osd=ONEOSD, pg=ONEPG)
|
||||
ERRORS += test_failure(cmd, "Must provide --type (filestore, memstore, keyvaluestore-dev)")
|
||||
|
||||
# Don't specify a data-path
|
||||
cmd = "./ceph_objectstore_tool --journal-path dev/{osd}.journal --type memstore --op list --pgid {pg}".format(osd=ONEOSD, pg=ONEPG)
|
||||
ERRORS += test_failure(cmd, "Must provide --data-path")
|
||||
|
||||
# Don't specify a journal-path for filestore
|
||||
cmd = "./ceph_objectstore_tool --type filestore --data-path dev/{osd} --op list --pgid {pg}".format(osd=ONEOSD, pg=ONEPG)
|
||||
ERRORS += test_failure(cmd, "Must provide --journal-path")
|
||||
|
||||
# Test --op list and generate json for all objects
|
||||
print "Test --op list by generating json for all objects"
|
||||
TMPFILE = r"/tmp/tmp.{pid}".format(pid=pid)
|
||||
ALLPGS = OBJREPPGS + OBJECPGS
|
||||
for pg in ALLPGS:
|
||||
OSDS = get_osds(pg, OSDDIR)
|
||||
for osd in OSDS:
|
||||
cmd = (CFSD_PREFIX + "--type list --pgid {pg}").format(osd=osd, pg=pg)
|
||||
cmd = (CFSD_PREFIX + "--op list --pgid {pg}").format(osd=osd, pg=pg)
|
||||
tmpfd = open(TMPFILE, "a")
|
||||
logging.debug(cmd)
|
||||
ret = call(cmd, shell=True, stdout=tmpfd)
|
||||
if ret != 0:
|
||||
logging.error("Bad exit status {ret} from --type list request".format(ret=ret))
|
||||
logging.error("Bad exit status {ret} from --op list request".format(ret=ret))
|
||||
ERRORS += 1
|
||||
|
||||
tmpfd.close()
|
||||
@ -487,7 +499,7 @@ def main():
|
||||
print "Test pg info"
|
||||
for pg in ALLREPPGS + ALLECPGS:
|
||||
for osd in get_osds(pg, OSDDIR):
|
||||
cmd = (CFSD_PREFIX + "--type info --pgid {pg} | grep '\"pgid\": \"{pg}\"'").format(osd=osd, pg=pg)
|
||||
cmd = (CFSD_PREFIX + "--op info --pgid {pg} | grep '\"pgid\": \"{pg}\"'").format(osd=osd, pg=pg)
|
||||
logging.debug(cmd)
|
||||
ret = call(cmd, shell=True, stdout=nullfd)
|
||||
if ret != 0:
|
||||
@ -498,7 +510,7 @@ def main():
|
||||
for pg in ALLREPPGS + ALLECPGS:
|
||||
for osd in get_osds(pg, OSDDIR):
|
||||
tmpfd = open(TMPFILE, "w")
|
||||
cmd = (CFSD_PREFIX + "--type log --pgid {pg}").format(osd=osd, pg=pg)
|
||||
cmd = (CFSD_PREFIX + "--op log --pgid {pg}").format(osd=osd, pg=pg)
|
||||
logging.debug(cmd)
|
||||
ret = call(cmd, shell=True, stdout=tmpfd)
|
||||
if ret != 0:
|
||||
@ -530,7 +542,7 @@ def main():
|
||||
for osd in get_osds(pg, OSDDIR):
|
||||
mydir = os.path.join(TESTDIR, osd)
|
||||
fname = os.path.join(mydir, pg)
|
||||
cmd = (CFSD_PREFIX + "--type export --pgid {pg} --file {file}").format(osd=osd, pg=pg, file=fname)
|
||||
cmd = (CFSD_PREFIX + "--op export --pgid {pg} --file {file}").format(osd=osd, pg=pg, file=fname)
|
||||
logging.debug(cmd)
|
||||
ret = call(cmd, shell=True, stdout=nullfd, stderr=nullfd)
|
||||
if ret != 0:
|
||||
@ -543,7 +555,7 @@ def main():
|
||||
RM_ERRORS = 0
|
||||
for pg in ALLREPPGS + ALLECPGS:
|
||||
for osd in get_osds(pg, OSDDIR):
|
||||
cmd = (CFSD_PREFIX + "--type remove --pgid {pg}").format(pg=pg, osd=osd)
|
||||
cmd = (CFSD_PREFIX + "--op remove --pgid {pg}").format(pg=pg, osd=osd)
|
||||
logging.debug(cmd)
|
||||
ret = call(cmd, shell=True, stdout=nullfd)
|
||||
if ret != 0:
|
||||
@ -559,7 +571,7 @@ def main():
|
||||
dir = os.path.join(TESTDIR, osd)
|
||||
for pg in [f for f in os.listdir(dir) if os.path.isfile(os.path.join(dir, f))]:
|
||||
file = os.path.join(dir, pg)
|
||||
cmd = (CFSD_PREFIX + "--type import --file {file}").format(osd=osd, file=file)
|
||||
cmd = (CFSD_PREFIX + "--op import --file {file}").format(osd=osd, file=file)
|
||||
logging.debug(cmd)
|
||||
ret = call(cmd, shell=True, stdout=nullfd)
|
||||
if ret != 0:
|
||||
|
@ -11,20 +11,12 @@ ceph_kvstore_tool_LDADD = $(LIBOS) $(CEPH_GLOBAL)
|
||||
ceph_kvstore_tool_CXXFLAGS = $(UNITTEST_CXXFLAGS)
|
||||
bin_DEBUGPROGRAMS += ceph-kvstore-tool
|
||||
|
||||
|
||||
ceph_filestore_tool_SOURCES = tools/ceph_filestore_tool.cc
|
||||
ceph_filestore_tool_LDADD = $(LIBOSD) $(LIBOS) $(CEPH_GLOBAL) -lboost_program_options
|
||||
ceph_objectstore_tool_SOURCES = tools/ceph_objectstore_tool.cc
|
||||
ceph_objectstore_tool_LDADD = $(LIBOSD) $(LIBOS) $(CEPH_GLOBAL) $(BOOST_PROGRAM_OPTIONS_LIBS)
|
||||
if LINUX
|
||||
ceph_filestore_tool_LDADD += -ldl
|
||||
ceph_objectstore_tool_LDADD += -ldl
|
||||
endif # LINUX
|
||||
bin_PROGRAMS += ceph_filestore_tool
|
||||
|
||||
ceph_filestore_dump_SOURCES = tools/ceph_filestore_dump.cc
|
||||
ceph_filestore_dump_LDADD = $(LIBOSD) $(LIBOS) $(CEPH_GLOBAL) $(BOOST_PROGRAM_OPTIONS_LIBS)
|
||||
if LINUX
|
||||
ceph_filestore_dump_LDADD += -ldl
|
||||
endif # LINUX
|
||||
bin_PROGRAMS += ceph_filestore_dump
|
||||
bin_PROGRAMS += ceph_objectstore_tool
|
||||
|
||||
monmaptool_SOURCES = tools/monmaptool.cc
|
||||
monmaptool_LDADD = $(CEPH_GLOBAL) $(LIBCOMMON)
|
||||
|
@ -411,9 +411,9 @@ static int get_fd_data(int fd, bufferlist &bl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void invalid_path(string &path)
|
||||
static void invalid_filestore_path(string &path)
|
||||
{
|
||||
cerr << "Invalid path to osd store specified: " << path << "\n";
|
||||
cerr << "Invalid filestore path specified: " << path << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -1481,36 +1481,38 @@ void usage(po::options_description &desc)
|
||||
cerr << std::endl;
|
||||
cerr << "Positional syntax:" << std::endl;
|
||||
cerr << std::endl;
|
||||
cerr << "(requires --filestore-path, --journal-path and --pgid to be specified)" << std::endl;
|
||||
cerr << "(requires --data, --journal (for filestore type) and --pgid to be specified)" << std::endl;
|
||||
cerr << "(optional [file] argument will read stdin or write stdout if not specified or if '-' specified)" << std::endl;
|
||||
cerr << "ceph-filestore-dump ... <object> (get|set)-bytes [file]" << std::endl;
|
||||
cerr << "ceph-filestore-dump ... <object> (set-(attr|omap) <key> [file]" << std::endl;
|
||||
cerr << "ceph-filestore-dump ... <object> (set-omaphdr) [file]" << std::endl;
|
||||
cerr << "ceph-filestore-dump ... <object> (get|rm)-(attr|omap) <key>" << std::endl;
|
||||
cerr << "ceph-filestore-dump ... <object> (get-omaphdr)" << std::endl;
|
||||
cerr << "ceph-filestore-dump ... <object> list-attrs" << std::endl;
|
||||
cerr << "ceph-filestore-dump ... <object> list-omap" << std::endl;
|
||||
cerr << "ceph-filestore-dump ... <object> remove" << std::endl;
|
||||
cerr << "ceph_objectstore_tool ... <object> (get|set)-bytes [file]" << std::endl;
|
||||
cerr << "ceph_objectstore_tool ... <object> (set-(attr|omap) <key> [file]" << std::endl;
|
||||
cerr << "ceph_objectstore_tool ... <object> (set-omaphdr) [file]" << std::endl;
|
||||
cerr << "ceph_objectstore_tool ... <object> (get|rm)-(attr|omap) <key>" << std::endl;
|
||||
cerr << "ceph_objectstore_tool ... <object> (get-omaphdr)" << std::endl;
|
||||
cerr << "ceph_objectstore_tool ... <object> list-attrs" << std::endl;
|
||||
cerr << "ceph_objectstore_tool ... <object> list-omap" << std::endl;
|
||||
cerr << "ceph_objectstore_tool ... <object> remove" << std::endl;
|
||||
cerr << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
string fspath, jpath, pgidstr, type, file, object, objcmd, arg1, arg2;
|
||||
string dpath, jpath, pgidstr, op, file, object, objcmd, arg1, arg2, type;
|
||||
ghobject_t ghobj;
|
||||
|
||||
po::options_description desc("Allowed options");
|
||||
desc.add_options()
|
||||
("help", "produce help message")
|
||||
("filestore-path", po::value<string>(&fspath),
|
||||
"path to filestore directory, mandatory")
|
||||
("journal-path", po::value<string>(&jpath),
|
||||
"path to journal, mandatory")
|
||||
("pgid", po::value<string>(&pgidstr),
|
||||
"PG id, mandatory except for import")
|
||||
("type", po::value<string>(&type),
|
||||
"Arg is one of [info, log, remove, export, import, list]")
|
||||
"Arg is one of [filestore (default), memstore, keyvaluestore-dev]")
|
||||
("data-path", po::value<string>(&dpath),
|
||||
"path to object store, mandatory")
|
||||
("journal-path", po::value<string>(&jpath),
|
||||
"path to journal, mandatory for filestore type")
|
||||
("pgid", po::value<string>(&pgidstr),
|
||||
"PG id, mandatory except for import, list-lost, fix-lost")
|
||||
("op", po::value<string>(&op),
|
||||
"Arg is one of [info, log, remove, export, import, list, list-lost, fix-lost]")
|
||||
("file", po::value<string>(&file),
|
||||
"path of file to export or import")
|
||||
("debug", "Enable diagnostic output to stderr")
|
||||
@ -1547,11 +1549,14 @@ int main(int argc, char **argv)
|
||||
usage(desc);
|
||||
}
|
||||
|
||||
if (!vm.count("filestore-path")) {
|
||||
cerr << "Must provide --filestore-path" << std::endl;
|
||||
if (!vm.count("data-path")) {
|
||||
cerr << "Must provide --data-path" << std::endl;
|
||||
usage(desc);
|
||||
}
|
||||
if (!vm.count("journal-path")) {
|
||||
if (!vm.count("type")) {
|
||||
type = "filestore";
|
||||
}
|
||||
if (type == "filestore" && !vm.count("journal-path")) {
|
||||
cerr << "Must provide --journal-path" << std::endl;
|
||||
usage(desc);
|
||||
}
|
||||
@ -1559,16 +1564,16 @@ int main(int argc, char **argv)
|
||||
cerr << "Invalid syntax, missing command" << std::endl;
|
||||
usage(desc);
|
||||
}
|
||||
if (!vm.count("type") && !(vm.count("object") && vm.count("objcmd"))) {
|
||||
cerr << "Must provide --type or object command..."
|
||||
<< std::endl;
|
||||
if (!vm.count("op") && !(vm.count("object") && vm.count("objcmd"))) {
|
||||
cerr << "Must provide --op or object command..." << std::endl;
|
||||
usage(desc);
|
||||
}
|
||||
if (vm.count("type") && vm.count("object")) {
|
||||
cerr << "Can't specify both --type and object command syntax" << std::endl;
|
||||
if (vm.count("op") && vm.count("object")) {
|
||||
cerr << "Can't specify both --op and object command syntax" << std::endl;
|
||||
usage(desc);
|
||||
}
|
||||
if (type != "import" && !vm.count("pgid")) {
|
||||
if (op != "import" && op != "list-lost" && op != "fix-lost"
|
||||
&& !vm.count("pgid")) {
|
||||
cerr << "Must provide pgid" << std::endl;
|
||||
usage(desc);
|
||||
}
|
||||
@ -1588,7 +1593,7 @@ int main(int argc, char **argv)
|
||||
outistty = isatty(STDOUT_FILENO);
|
||||
|
||||
file_fd = fd_none;
|
||||
if (type == "export") {
|
||||
if (op == "export") {
|
||||
if (!vm.count("file")) {
|
||||
if (outistty) {
|
||||
cerr << "stdout is a tty and no --file option specified" << std::endl;
|
||||
@ -1598,7 +1603,7 @@ int main(int argc, char **argv)
|
||||
} else {
|
||||
file_fd = open(file.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
||||
}
|
||||
} else if (type == "import") {
|
||||
} else if (op == "import") {
|
||||
if (!vm.count("file")) {
|
||||
if (isatty(STDIN_FILENO)) {
|
||||
cerr << "stdin is a tty and no --file option specified" << std::endl;
|
||||
@ -1620,13 +1625,12 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((fspath.length() == 0 || jpath.length() == 0) ||
|
||||
(type != "import" && pgidstr.length() == 0)) {
|
||||
if (dpath.length() == 0) {
|
||||
cerr << "Invalid params" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (type == "import" && pgidstr.length()) {
|
||||
if (op == "import" && pgidstr.length()) {
|
||||
cerr << "--pgid option invalid with import" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
@ -1665,30 +1669,33 @@ int main(int argc, char **argv)
|
||||
}
|
||||
g_conf->apply_changes(NULL);
|
||||
|
||||
//Verify that fspath really is an osd store
|
||||
//Verify that data-path really exists
|
||||
struct stat st;
|
||||
if (::stat(fspath.c_str(), &st) == -1) {
|
||||
perror("fspath");
|
||||
invalid_path(fspath);
|
||||
if (::stat(dpath.c_str(), &st) == -1) {
|
||||
perror("data-path");
|
||||
exit(1);
|
||||
}
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
invalid_path(fspath);
|
||||
}
|
||||
string check = fspath + "/whoami";
|
||||
if (::stat(check.c_str(), &st) == -1) {
|
||||
perror("whoami");
|
||||
invalid_path(fspath);
|
||||
}
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
invalid_path(fspath);
|
||||
}
|
||||
check = fspath + "/current";
|
||||
if (::stat(check.c_str(), &st) == -1) {
|
||||
perror("current");
|
||||
invalid_path(fspath);
|
||||
}
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
invalid_path(fspath);
|
||||
//Verify data data-path really is a filestore
|
||||
if (type == "filestore") {
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
invalid_filestore_path(dpath);
|
||||
}
|
||||
string check = dpath + "/whoami";
|
||||
if (::stat(check.c_str(), &st) == -1) {
|
||||
perror("whoami");
|
||||
invalid_filestore_path(dpath);
|
||||
}
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
invalid_filestore_path(dpath);
|
||||
}
|
||||
check = dpath + "/current";
|
||||
if (::stat(check.c_str(), &st) == -1) {
|
||||
perror("current");
|
||||
invalid_filestore_path(dpath);
|
||||
}
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
invalid_filestore_path(dpath);
|
||||
}
|
||||
}
|
||||
|
||||
spg_t pgid;
|
||||
@ -1697,7 +1704,11 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
ObjectStore *fs = ObjectStore::create(NULL, "filestore", fspath, jpath, flags);
|
||||
ObjectStore *fs = ObjectStore::create(NULL, type, dpath, jpath, flags);
|
||||
if (fs == NULL) {
|
||||
cerr << "Must provide --type (filestore, memstore, keyvaluestore-dev)" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int r = fs->mount();
|
||||
if (r < 0) {
|
||||
@ -1766,7 +1777,7 @@ int main(int argc, char **argv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (type == "import") {
|
||||
if (op == "import") {
|
||||
|
||||
try {
|
||||
ret = do_import(fs, superblock);
|
||||
@ -1786,7 +1797,7 @@ int main(int argc, char **argv)
|
||||
log_oid = OSD::make_pg_log_oid(pgid);
|
||||
biginfo_oid = OSD::make_pg_biginfo_oid(pgid);
|
||||
|
||||
if (type == "remove") {
|
||||
if (op == "remove") {
|
||||
uint64_t next_removal_seq = 0; //My local seq
|
||||
finish_remove_pgs(fs, &next_removal_seq);
|
||||
int r = initiate_new_remove_pg(fs, pgid, &next_removal_seq);
|
||||
@ -1800,6 +1811,104 @@ int main(int argc, char **argv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (op == "list-lost" || op == "fix-lost") {
|
||||
unsigned LIST_AT_A_TIME = 100;
|
||||
unsigned scanned = 0;
|
||||
int r;
|
||||
vector<coll_t> colls_to_check;
|
||||
if (pgidstr.length()) {
|
||||
colls_to_check.push_back(coll_t(pgid));
|
||||
} else {
|
||||
vector<coll_t> candidates;
|
||||
r = fs->list_collections(candidates);
|
||||
if (r < 0) {
|
||||
cerr << "Error listing collections: " << cpp_strerror(r) << std::endl;
|
||||
goto UMOUNT;
|
||||
}
|
||||
for (vector<coll_t>::iterator i = candidates.begin();
|
||||
i != candidates.end();
|
||||
++i) {
|
||||
spg_t pgid;
|
||||
snapid_t snap;
|
||||
if (i->is_pg(pgid, snap)) {
|
||||
colls_to_check.push_back(*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cerr << colls_to_check.size() << " pgs to scan" << std::endl;
|
||||
for (vector<coll_t>::iterator i = colls_to_check.begin();
|
||||
i != colls_to_check.end();
|
||||
++i, ++scanned) {
|
||||
cerr << "Scanning " << *i << ", " << scanned << "/"
|
||||
<< colls_to_check.size() << " completed" << std::endl;
|
||||
ghobject_t next;
|
||||
while (!next.is_max()) {
|
||||
vector<ghobject_t> list;
|
||||
r = fs->collection_list_partial(
|
||||
*i,
|
||||
next,
|
||||
LIST_AT_A_TIME,
|
||||
LIST_AT_A_TIME,
|
||||
CEPH_NOSNAP,
|
||||
&list,
|
||||
&next);
|
||||
if (r < 0) {
|
||||
cerr << "Error listing collection: " << *i << ", "
|
||||
<< cpp_strerror(r) << std::endl;
|
||||
goto UMOUNT;
|
||||
}
|
||||
for (vector<ghobject_t>::iterator obj = list.begin();
|
||||
obj != list.end();
|
||||
++obj) {
|
||||
bufferlist attr;
|
||||
r = fs->getattr(*i, *obj, OI_ATTR, attr);
|
||||
if (r < 0) {
|
||||
cerr << "Error getting attr on : " << make_pair(*i, *obj) << ", "
|
||||
<< cpp_strerror(r) << std::endl;
|
||||
goto UMOUNT;
|
||||
}
|
||||
object_info_t oi;
|
||||
bufferlist::iterator bp = attr.begin();
|
||||
try {
|
||||
::decode(oi, bp);
|
||||
} catch (...) {
|
||||
r = -EINVAL;
|
||||
cerr << "Error getting attr on : " << make_pair(*i, *obj) << ", "
|
||||
<< cpp_strerror(r) << std::endl;
|
||||
goto UMOUNT;
|
||||
}
|
||||
if (oi.is_lost()) {
|
||||
if (op == "list-lost") {
|
||||
cout << *i << "/" << *obj << " is lost" << std::endl;
|
||||
}
|
||||
if (op == "fix-lost") {
|
||||
cerr << *i << "/" << *obj << " is lost, fixing" << std::endl;
|
||||
oi.clear_flag(object_info_t::FLAG_LOST);
|
||||
bufferlist bl2;
|
||||
::encode(oi, bl2);
|
||||
ObjectStore::Transaction t;
|
||||
t.setattr(*i, *obj, OI_ATTR, bl2);
|
||||
r = fs->apply_transaction(t);
|
||||
if (r < 0) {
|
||||
cerr << "Error getting fixing attr on : " << make_pair(*i, *obj)
|
||||
<< ", "
|
||||
<< cpp_strerror(r) << std::endl;
|
||||
goto UMOUNT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cerr << "Completed" << std::endl;
|
||||
|
||||
UMOUNT:
|
||||
fs->sync_and_flush();
|
||||
ret = r;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = fs->list_collections(ls);
|
||||
if (r < 0) {
|
||||
cerr << "failed to list pgs: " << cpp_strerror(-r) << std::endl;
|
||||
@ -1997,7 +2106,7 @@ int main(int argc, char **argv)
|
||||
usage(desc);
|
||||
}
|
||||
|
||||
if (type == "list") {
|
||||
if (op == "list") {
|
||||
Formatter *formatter = new JSONFormatter(false);
|
||||
r = do_list(fs, coll, formatter);
|
||||
if (r) {
|
||||
@ -2029,17 +2138,17 @@ int main(int argc, char **argv)
|
||||
if (debug)
|
||||
cerr << "struct_v " << (int)struct_ver << std::endl;
|
||||
|
||||
if (type == "export") {
|
||||
if (op == "export") {
|
||||
ret = do_export(fs, coll, pgid, info, map_epoch, struct_ver, superblock);
|
||||
if (ret == 0 && file_fd != STDOUT_FILENO)
|
||||
cout << "Export successful" << std::endl;
|
||||
} else if (type == "info") {
|
||||
} else if (op == "info") {
|
||||
formatter->open_object_section("info");
|
||||
info.dump(formatter);
|
||||
formatter->close_section();
|
||||
formatter->flush(cout);
|
||||
cout << std::endl;
|
||||
} else if (type == "log") {
|
||||
} else if (op == "log") {
|
||||
PGLog::IndexedLog log;
|
||||
pg_missing_t missing;
|
||||
ret = get_log(fs, coll, pgid, info, log, missing);
|
||||
@ -2057,7 +2166,7 @@ int main(int argc, char **argv)
|
||||
formatter->flush(cout);
|
||||
cout << std::endl;
|
||||
} else {
|
||||
cerr << "Must provide --type (info, log, remove, export, import, list)"
|
||||
cerr << "Must provide --op (info, log, remove, export, import, list, list-lost, fix-lost)"
|
||||
<< std::endl;
|
||||
usage(desc);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user