return *_dout << "mds." << rank << ".purge_queue ";
}
-const std::map<std::string_view, PurgeItem::Action> PurgeItem::actions = {
- {"NONE", PurgeItem::NONE},
- {"PURGE_FILE", PurgeItem::PURGE_FILE},
- {"TRUNCATE_FILE", PurgeItem::TRUNCATE_FILE},
- {"PURGE_DIR", PurgeItem::PURGE_DIR}
-};
-
void PurgeItem::encode(bufferlist &bl) const
{
ENCODE_START(1, 1, bl);
- encode(stamp, bl);
- encode(pad_size, bl);
- uint8_t static const pad = 0xff;
- for (unsigned int i = 0; i<pad_size; i++) {
- encode(pad, bl);
- }
encode((uint8_t)action, bl);
encode(ino, bl);
encode(size, bl);
void PurgeItem::decode(bufferlist::const_iterator &p)
{
DECODE_START(1, p);
- decode(stamp, p);
- decode(pad_size, p);
- p.advance(pad_size);
decode((uint8_t&)action, p);
decode(ino, p);
decode(size, p);
return false;
}
-std::string PurgeItem::get_type_str() const
-{
- switch(action) {
- case PurgeItem::NONE: return "NONE";
- case PurgeItem::PURGE_FILE: return "PURGE_FILE";
- case PurgeItem::PURGE_DIR: return "PURGE_DIR";
- case PurgeItem::TRUNCATE_FILE: return "TRUNCATE_FILE";
- default:
- return "UNKNOWN";
- }
-}
-
PURGE_DIR
};
- utime_t stamp;
- //None PurgeItem serves as NoOp for splicing out journal entries;
- //so there has to be a "pad_size" to specify the size of journal
- //space to be spliced.
- uint32_t pad_size;
Action action;
inodeno_t ino;
uint64_t size;
fragtree_t fragtree;
PurgeItem()
- : stamp(ceph_clock_now()), pad_size(0), action(NONE), ino(0), size(0)
+ : action(NONE), ino(0), size(0)
{}
void encode(bufferlist &bl) const;
void decode(bufferlist::const_iterator &p);
-
- static Action str_to_type(std::string_view str) {
- return PurgeItem::actions.at(str);
- }
-
- void dump(Formatter *f) const
- {
- f->dump_int("action", action);
- f->dump_int("ino", ino);
- f->dump_int("size", size);
- f->open_object_section("layout");
- layout.dump(f);
- f->close_section();
- f->open_object_section("SnapContext");
- snapc.dump(f);
- f->close_section();
- f->open_object_section("fragtree");
- fragtree.dump(f);
- f->close_section();
- }
-
- std::string get_type_str() const;
-private:
- static const std::map<std::string_view, PurgeItem::Action> actions;
};
WRITE_CLASS_ENCODER(PurgeItem)
}
for (JournalScanner::EventMap::const_iterator i = scan.events.begin(); i != scan.events.end(); ++i) {
- bufferlist bin;
- std::stringstream filename;
- if (i->second.log_event) {
- LogEvent *le = i->second.log_event;
- le->encode(bin, CEPH_FEATURES_SUPPORTED_DEFAULT);
- filename << "0x" << std::hex << i->first << std::dec << "_" << le->get_type_str() << ".bin";
- } else if (i->second.pi) {
- PurgeItem* pi = i->second.pi;
- pi->encode(bin);
- filename << "0x" << std::hex << i->first << std::dec << "_" << pi->get_type_str() << ".bin";
- }
+ LogEvent *le = i->second.log_event;
+ bufferlist le_bin;
+ le->encode(le_bin, CEPH_FEATURES_SUPPORTED_DEFAULT);
+ std::stringstream filename;
+ filename << "0x" << std::hex << i->first << std::dec << "_" << le->get_type_str() << ".bin";
std::string const file_path = path + std::string("/") + filename.str();
std::ofstream bin_file(file_path.c_str(), std::ofstream::out | std::ofstream::binary);
- bin.write_stream(bin_file);
+ le_bin.write_stream(bin_file);
bin_file.close();
if (bin_file.fail()) {
return -EIO;
jf.open_array_section("journal");
{
for (JournalScanner::EventMap::const_iterator i = scan.events.begin(); i != scan.events.end(); ++i) {
- if (i->second.log_event) {
- LogEvent *le = i->second.log_event;
- jf.open_object_section("log_event");
- {
- le->dump(&jf);
- }
- jf.close_section(); // log_event
- } else if (i->second.pi) {
- PurgeItem* pi = i->second.pi;
- jf.open_object_section("purge_action");
- pi->dump(&jf);
- jf.close_section();
+ LogEvent *le = i->second.log_event;
+ jf.open_object_section("log_event");
+ {
+ le->dump(&jf);
}
+ jf.close_section(); // log_event
}
}
jf.close_section(); // journal
void EventOutput::list() const
{
for (JournalScanner::EventMap::const_iterator i = scan.events.begin(); i != scan.events.end(); ++i) {
- if (i->second.log_event) {
- std::vector<std::string> ev_paths;
- EMetaBlob const *emb = i->second.log_event->get_metablob();
- if (emb) {
- emb->get_paths(ev_paths);
- }
+ std::vector<std::string> ev_paths;
+ EMetaBlob const *emb = i->second.log_event->get_metablob();
+ if (emb) {
+ emb->get_paths(ev_paths);
+ }
- std::string detail;
- if (i->second.log_event->get_type() == EVENT_UPDATE) {
- EUpdate *eu = reinterpret_cast<EUpdate*>(i->second.log_event);
- detail = eu->type;
- }
+ std::string detail;
+ if (i->second.log_event->get_type() == EVENT_UPDATE) {
+ EUpdate *eu = reinterpret_cast<EUpdate*>(i->second.log_event);
+ detail = eu->type;
+ }
- std::cout <<i->second.log_event->get_stamp() << " 0x"
- << std::hex << i->first << std::dec << " "
- << i->second.log_event->get_type_str() << ": "
- << " (" << detail << ")" << std::endl;
- for (std::vector<std::string>::iterator i = ev_paths.begin(); i != ev_paths.end(); ++i) {
- std::cout << " " << *i << std::endl;
- }
- } else if (i->second.pi) {
- std::cout << i->second.pi->stamp << " 0x"
- << std::hex << i->first << std::dec << " "
- << i->second.pi->get_type_str() << std::endl;
+ std::cout <<i->second.log_event->get_stamp() << " 0x"
+ << std::hex << i->first << std::dec << " "
+ << i->second.log_event->get_type_str() << ": "
+ << " (" << detail << ")" << std::endl;
+ for (std::vector<std::string>::iterator i = ev_paths.begin(); i != ev_paths.end(); ++i) {
+ std::cout << " " << *i << std::endl;
}
}
}
{
std::map<std::string, int> type_count;
for (JournalScanner::EventMap::const_iterator i = scan.events.begin(); i != scan.events.end(); ++i) {
- std::string type;
- if (i->second.log_event)
- type = i->second.log_event->get_type_str();
- else if (i->second.pi)
- type = i->second.pi->get_type_str();
+ std::string const type = i->second.log_event->get_type_str();
if (type_count.count(type) == 0) {
type_count[type] = 0;
}
const string JournalFilter::range_separator("..");
-bool JournalFilter::apply(uint64_t pos, PurgeItem &pi) const
-{
- /* Filtering by journal offset range */
- if (pos < range_start || pos >= range_end) {
- return false;
- }
-
- if (purge_action != PurgeItem::NONE) {
- if (pi.action != purge_action)
- return false;
- }
-
- if (inode) {
- if (inode != pi.ino)
- return false;
- }
- return true;
-}
/*
* Return whether a LogEvent is to be included or excluded.
}
}
} else if (ceph_argparse_witharg(argv, arg, &arg_str, "--path", (char*)NULL)) {
- if (!type.compare("purge_queue")) {
- derr << "Invalid filter arguments: purge_queue doesn't take \"--path\"." << dendl;
- return -EINVAL;
- }
dout(4) << "Filtering by path '" << arg_str << "'" << dendl;
path_expr = arg_str;
} else if (ceph_argparse_witharg(argv, arg, &arg_str, "--inode", (char*)NULL)) {
return -EINVAL;
}
} else if (ceph_argparse_witharg(argv, arg, &arg_str, "--type", (char*)NULL)) {
- try {
- if (!type.compare("mdlog")) {
- event_type = LogEvent::str_to_type(arg_str);
- } else if (!type.compare("purge_queue")) {
- purge_action = PurgeItem::str_to_type(arg_str);
- }
- } catch (std::out_of_range) {
- derr << "Invalid event type '" << arg_str << "'" << dendl;
- return -EINVAL;
+ std::string parse_err;
+ event_type = LogEvent::str_to_type(arg_str);
+ if (event_type == LogEvent::EventType(-1)) {
+ derr << "Invalid event type '" << arg_str << "': " << parse_err << dendl;
+ return -EINVAL;
}
+
} else if (ceph_argparse_witharg(argv, arg, &arg_str, "--frag", (char*)NULL)) {
- if (!type.compare("purge_queue")) {
- derr << "Invalid filter arguments: purge_queue doesn't take \"--frag\"." << dendl;
- return -EINVAL;
- }
std::string const frag_sep = ".";
size_t sep_loc = arg_str.find(frag_sep);
std::string inode_str;
frag = dirfrag_t(frag_ino, frag_t(frag_enc));
dout(4) << "dirfrag filter: '" << frag << "'" << dendl;
} else if (ceph_argparse_witharg(argv, arg, &arg_str, "--dname", (char*)NULL)) {
- if (!type.compare("purge_queue")) {
- derr << "Invalid filter arguments: purge_queue doesn't take \"--dname\"." << dendl;
- return -EINVAL;
- }
frag_dentry = arg_str;
dout(4) << "dentry filter: '" << frag_dentry << "'" << dendl;
} else if (ceph_argparse_witharg(argv, arg, &arg_str, "--client", (char*)NULL)) {
- if (!type.compare("purge_queue")) {
- derr << "Invalid filter arguments: purge_queue doesn't take \"--client\"." << dendl;
- return -EINVAL;
- }
-
std::string parse_err;
int64_t client_num = strict_strtoll(arg_str.c_str(), 0, &parse_err);
if (!parse_err.empty()) {
#include "mds/mdstypes.h"
#include "mds/LogEvent.h"
-#include "mds/PurgeQueue.h"
/**
* A set of conditions for narrowing down a search through the journal
/* Filtering by type */
LogEvent::EventType event_type;
- std::string type;
-
- /* Filtering by PurgeItem::Action */
- PurgeItem::Action purge_action;
-
/* Filtering by dirfrag */
dirfrag_t frag;
std::string frag_dentry; //< optional, filter dentry name within fragment
entity_name_t client_name;
public:
- JournalFilter(std::string t) :
+ JournalFilter() :
range_start(0),
range_end(-1),
inode(0),
- event_type(0),
- type(t),
- purge_action(PurgeItem::NONE) {}
+ event_type(0) {}
bool get_range(uint64_t &start, uint64_t &end) const;
bool apply(uint64_t pos, LogEvent &le) const;
- bool apply(uint64_t pos, PurgeItem &pi) const;
int parse_args(
std::vector<const char*> &argv,
std::vector<const char*>::iterator &arg);
valid_entry = false;
}
} else if (type == "purge_queue"){
- PurgeItem* pi = new PurgeItem();
+ PurgeItem pi;
try {
auto q = le_bl.cbegin();
- pi->decode(q);
- if (filter.apply(read_offset, *pi)) {
- events[read_offset] = EventRecord(pi, consumed);
- } else {
- delete pi;
- }
+ ::decode(pi, q);
} catch (const buffer::error &err) {
valid_entry = false;
}
}
dout(4) << events.size() << " events" << dendl;
for (EventMap::iterator i = events.begin(); i != events.end(); ++i) {
- if (i->second.log_event)
- delete i->second.log_event;
- else if (i->second.pi)
- delete i->second.pi;
+ delete i->second.log_event;
}
events.clear();
}
io(io_),
rank(rank_),
type(type_),
- filter(type_),
is_mdlog(false),
pointer_present(false),
pointer_valid(false),
class EventRecord {
public:
EventRecord() : log_event(NULL), raw_size(0) {}
- EventRecord(LogEvent *le, uint32_t rs) : log_event(le), pi(NULL), raw_size(rs) {}
- EventRecord(PurgeItem* p, uint32_t rs) : log_event(NULL), pi(p), raw_size(rs) {}
+ EventRecord(LogEvent *le, uint32_t rs) : log_event(le), raw_size(rs) {}
LogEvent *log_event;
- PurgeItem *pi;
uint32_t raw_size; //< Size from start offset including all encoding overhead
};
r = main_journal(argv);
} else if (mode == std::string("header")) {
r = main_header(argv);
- } else if (mode == std::string("event")) {
+ } else if (type == std::string("mdlog") && mode == std::string("event")) {
r = main_event(argv);
} else {
cerr << "Bad command '" << mode << "'" << std::endl;
*/
int JournalTool::main_header(std::vector<const char*> &argv)
{
- JournalFilter filter(type);
+ JournalFilter filter;
JournalScanner js(input, rank, type, filter);
int r = js.scan(false);
if (r < 0) {
return -EINVAL;
}
- if (command == "recover_dentries" && type != "mdlog") {
- derr << "journaler for " << type << " can't do \"recover_dentries\"." << dendl;
- return -EINVAL;
- }
-
if (arg == argv.end()) {
derr << "Incomplete command line" << dendl;
return -EINVAL;
// Parse filter options
// ====================
- JournalFilter filter(type);
+ JournalFilter filter;
r = filter.parse_args(argv, arg);
if (r) {
return r;
{
int r;
- JournalFilter filter(type);
+ JournalFilter filter;
JournalScanner js(input, rank, type, filter);
r = js.scan();
if (r) {
// is needed inside the ENoOp to make up the difference.
bufferlist tmp;
ENoOp enoop(0);
- PurgeItem pi;
-
- if (type == "mdlog") {
- enoop.encode_with_header(tmp, CEPH_FEATURES_SUPPORTED_DEFAULT);
- } else if (type == "purge_queue") {
- pi.encode(tmp);
- }
+ enoop.encode_with_header(tmp, CEPH_FEATURES_SUPPORTED_DEFAULT);
dout(4) << "erase_region " << pos << " len=" << length << dendl;
return -EINVAL;
}
+ // Serialize an ENoOp with the correct amount of padding
+ enoop = ENoOp(padding);
bufferlist entry;
- if (type == "mdlog") {
- // Serialize an ENoOp with the correct amount of padding
- enoop = ENoOp(padding);
- enoop.encode_with_header(entry, CEPH_FEATURES_SUPPORTED_DEFAULT);
- } else if (type == "purge_queue") {
- pi.pad_size = padding;
- pi.encode(entry);
- }
+ enoop.encode_with_header(entry, CEPH_FEATURES_SUPPORTED_DEFAULT);
JournalStream stream(JOURNAL_FORMAT_RESILIENT);
+
// Serialize region of log stream
bufferlist log_data;
stream.write(entry, &log_data, pos);