X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Ftools%2Frados%2FPoolDump.cc;fp=src%2Fceph%2Fsrc%2Ftools%2Frados%2FPoolDump.cc;h=ad7a1a4dfefb85406cbf16d5011858ae90da4c5c;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/tools/rados/PoolDump.cc b/src/ceph/src/tools/rados/PoolDump.cc new file mode 100644 index 0000000..ad7a1a4 --- /dev/null +++ b/src/ceph/src/tools/rados/PoolDump.cc @@ -0,0 +1,170 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2015 Red Hat + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "include/rados/librados.hpp" +#include "common/errno.h" + +#include "PoolDump.h" + +using namespace librados; + +#define dout_context g_ceph_context +#define dout_subsys ceph_subsys_rados + +/** + * Export RADOS objects from a live cluster + * to a serialized format via a file descriptor. + * + * @returns 0 on success, else error code + */ +int PoolDump::dump(IoCtx *io_ctx) +{ + assert(io_ctx != NULL); + + int r = 0; + write_super(); + + r = write_simple(TYPE_POOL_BEGIN, file_fd); + if (r != 0) { + return r; + } + + io_ctx->set_namespace(all_nspaces); + librados::NObjectIterator i = io_ctx->nobjects_begin(); + + librados::NObjectIterator i_end = io_ctx->nobjects_end(); + for (; i != i_end; ++i) { + const std::string oid = i->get_oid(); + dout(10) << "OID '" << oid << "'" << dendl; + + // Compose OBJECT_BEGIN + // ==================== + object_begin obj_begin; + obj_begin.hoid.hobj.oid = i->get_oid(); + obj_begin.hoid.hobj.nspace = i->get_nspace(); + obj_begin.hoid.hobj.set_key(i->get_locator()); + + // Only output head, RadosImport only wants that + obj_begin.hoid.hobj.snap = CEPH_NOSNAP; + + // Skip setting object_begin.oi, RadosImport doesn't care + + r = write_section(TYPE_OBJECT_BEGIN, obj_begin, file_fd); + if (r != 0) { + return r; + } + + // Compose TYPE_DATA chunks + // ======================== + const uint32_t op_size = 4096 * 1024; + uint64_t offset = 0; + io_ctx->set_namespace(i->get_nspace()); + while (true) { + bufferlist outdata; + r = io_ctx->read(oid, outdata, op_size, offset); + if (r <= 0) { + // Error or no data + break; + } + + r = write_section(TYPE_DATA, + data_section(offset, outdata.length(), outdata), file_fd); + if (r != 0) { + // Output stream error + return r; + } + + if (outdata.length() < op_size) { + // No more data + r = 0; + break; + } + offset += outdata.length(); + } + + // Compose TYPE_ATTRS chunk + // ======================== + std::map raw_xattrs; + std::map xattrs; + r = io_ctx->getxattrs(oid, raw_xattrs); + if (r < 0) { + cerr << "error getting xattr set " << oid << ": " << cpp_strerror(r) + << std::endl; + return r; + } + // Prepend "_" to mimic how user keys are represented in a pg export + for (std::map::iterator i = raw_xattrs.begin(); + i != raw_xattrs.end(); ++i) { + std::pair< std::string, bufferlist> item(std::string("_") + std::string(i->first.c_str()), i->second); + xattrs.insert(item); + } + r = write_section(TYPE_ATTRS, attr_section(xattrs), file_fd); + if (r != 0) { + return r; + } + + // Compose TYPE_OMAP_HDR section + // ============================= + bufferlist omap_header; + r = io_ctx->omap_get_header(oid, &omap_header); + if (r < 0) { + cerr << "error getting omap header " << oid + << ": " << cpp_strerror(r) << std::endl; + return r; + } + r = write_section(TYPE_OMAP_HDR, omap_hdr_section(omap_header), file_fd); + if (r != 0) { + return r; + } + + // Compose TYPE_OMAP + int MAX_READ = 512; + string last_read = ""; + do { + map values; + r = io_ctx->omap_get_vals(oid, last_read, MAX_READ, &values); + if (r < 0) { + cerr << "error getting omap keys " << oid << ": " + << cpp_strerror(r) << std::endl; + return r; + } + if (values.size()) { + last_read = values.rbegin()->first; + } else { + break; + } + + r = write_section(TYPE_OMAP, omap_section(values), file_fd); + if (r != 0) { + return r; + } + r = values.size(); + } while (r == MAX_READ); + r = 0; + + // Close object + // ============= + r = write_simple(TYPE_OBJECT_END, file_fd); + if (r != 0) { + return r; + } + } + + r = write_simple(TYPE_POOL_END, file_fd); +#if defined(__linux__) + if (file_fd != STDOUT_FILENO) + posix_fadvise(file_fd, 0, 0, POSIX_FADV_DONTNEED); +#endif + return r; +}