X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fmon%2FMonOpRequest.h;fp=src%2Fceph%2Fsrc%2Fmon%2FMonOpRequest.h;h=7a43bff2f60256335c77e6248c1cfcb3979e4eb7;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/mon/MonOpRequest.h b/src/ceph/src/mon/MonOpRequest.h new file mode 100644 index 0000000..7a43bff --- /dev/null +++ b/src/ceph/src/mon/MonOpRequest.h @@ -0,0 +1,247 @@ +// -*- 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 + * Copyright (C) 2015 SUSE LINUX GmbH + * + * 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. + */ + +#ifndef MON_OPREQUEST_H_ +#define MON_OPREQUEST_H_ +#include +#include + +#include "common/TrackedOp.h" +#include "include/memory.h" +#include "mon/Session.h" +#include "msg/Message.h" + +struct MonOpRequest : public TrackedOp { + friend class OpTracker; + + void mark_dispatch() { + mark_event("monitor_dispatch"); + } + void mark_wait_for_quorum() { + mark_event("wait_for_quorum"); + } + void mark_zap() { + mark_event("monitor_zap"); + } + void mark_forwarded() { + mark_event("forwarded"); + forwarded_to_leader = true; + } + + void mark_svc_event(const string &service, const string &event) { + string s = service; + s.append(":").append(event); + mark_event_string(s); + } + + void mark_logmon_event(const string &event) { + mark_svc_event("logm", event); + } + void mark_osdmon_event(const string &event) { + mark_svc_event("osdmap", event); + } + void mark_pgmon_event(const string &event) { + mark_svc_event("pgmap", event); + } + void mark_mdsmon_event(const string &event) { + mark_svc_event("mdsmap", event); + } + void mark_authmon_event(const string &event) { + mark_svc_event("auth", event); + } + void mark_paxos_event(const string &event) { + mark_svc_event("paxos", event); + } + + + enum op_type_t { + OP_TYPE_NONE = 0, ///< no type defined (default) + OP_TYPE_SERVICE, ///< belongs to a Paxos Service or similar + OP_TYPE_MONITOR, ///< belongs to the Monitor class + OP_TYPE_ELECTION, ///< belongs to the Elector class + OP_TYPE_PAXOS, ///< refers to Paxos messages + OP_TYPE_COMMAND, ///< is a command + }; + + MonOpRequest(const MonOpRequest &other) = delete; + MonOpRequest & operator = (const MonOpRequest &other) = delete; + +private: + Message *request; + utime_t dequeued_time; + MonSession *session; + ConnectionRef con; + bool forwarded_to_leader; + op_type_t op_type; + + MonOpRequest(Message *req, OpTracker *tracker) : + TrackedOp(tracker, + req->get_recv_stamp().is_zero() ? + ceph_clock_now() : req->get_recv_stamp()), + request(req), + session(NULL), + con(NULL), + forwarded_to_leader(false), + op_type(OP_TYPE_NONE) + { + mark_event("header_read", request->get_recv_stamp()); + mark_event("throttled", request->get_throttle_stamp()); + mark_event("all_read", request->get_recv_complete_stamp()); + mark_event("dispatched", request->get_dispatch_stamp()); + + if (req) { + con = req->get_connection(); + if (con) { + session = static_cast(con->get_priv()); + } + } + } + + void _dump(Formatter *f) const override { + { + f->open_array_section("events"); + Mutex::Locker l(lock); + for (auto& i : events) { + f->dump_object("event", i); + } + f->close_section(); + f->open_object_section("info"); + f->dump_int("seq", seq); + f->dump_bool("src_is_mon", is_src_mon()); + f->dump_stream("source") << request->get_source_inst(); + f->dump_bool("forwarded_to_leader", forwarded_to_leader); + f->close_section(); + } + } + +protected: + void _dump_op_descriptor_unlocked(ostream& stream) const override { + get_req()->print(stream); + } + +public: + ~MonOpRequest() override { + request->put(); + // certain ops may not have a session (e.g., AUTH or PING) + if (session) + session->put(); + } + + MonSession *get_session() const { + if (!session) + return NULL; + return session; + } + + template + T *get_req() const { return static_cast(request); } + + Message *get_req() const { return get_req(); } + + int get_req_type() const { + if (!request) + return 0; + return request->get_type(); + } + + ConnectionRef get_connection() { return con; } + + void set_session(MonSession *s) { + if (session) { + // we will be rewriting the existing session; drop the ref. + session->put(); + } + + if (s == NULL) { + session = NULL; + } else { + session = static_cast(s->get()); + } + } + + bool is_src_mon() const { + return (con && con->get_peer_type() & CEPH_ENTITY_TYPE_MON); + } + + typedef boost::intrusive_ptr Ref; + + void set_op_type(op_type_t t) { + op_type = t; + } + void set_type_service() { + set_op_type(OP_TYPE_SERVICE); + } + void set_type_monitor() { + set_op_type(OP_TYPE_MONITOR); + } + void set_type_paxos() { + set_op_type(OP_TYPE_PAXOS); + } + void set_type_election() { + set_op_type(OP_TYPE_ELECTION); + } + void set_type_command() { + set_op_type(OP_TYPE_COMMAND); + } + + op_type_t get_op_type() { + return op_type; + } + + bool is_type_service() { + return (get_op_type() == OP_TYPE_SERVICE); + } + bool is_type_monitor() { + return (get_op_type() == OP_TYPE_MONITOR); + } + bool is_type_paxos() { + return (get_op_type() == OP_TYPE_PAXOS); + } + bool is_type_election() { + return (get_op_type() == OP_TYPE_ELECTION); + } + bool is_type_command() { + return (get_op_type() == OP_TYPE_COMMAND); + } +}; + +typedef MonOpRequest::Ref MonOpRequestRef; + +struct C_MonOp : public Context +{ + MonOpRequestRef op; + + explicit C_MonOp(MonOpRequestRef o) : + op(o) { } + + void finish(int r) override { + if (op && r == -ECANCELED) { + op->mark_event("callback canceled"); + } else if (op && r == -EAGAIN) { + op->mark_event("callback retry"); + } else if (op && r == 0) { + op->mark_event("callback finished"); + } + _finish(r); + } + + void mark_op_event(const string &event) { + if (op) + op->mark_event_string(event); + } + + virtual void _finish(int r) = 0; +}; + +#endif /* MON_OPREQUEST_H_ */