ceph/branches/riccardo/monitor2/msg/Message.h
riccardo80 07ac5d3e74 creating branch for distributed monitor
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1068 29311d96-e01e-0410-9327-a35deaab8ce9
2007-02-01 05:43:23 +00:00

439 lines
12 KiB
C++

// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
/*
* Ceph - scalable distributed file system
*
* Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
*
* 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 __MESSAGE_H
#define __MESSAGE_H
#define MSG_CLOSE 0
#define MSG_NS_CONNECT 1
#define MSG_NS_CONNECTACK 2
#define MSG_NS_REGISTER 3
#define MSG_NS_REGISTERACK 4
#define MSG_NS_STARTED 5
#define MSG_NS_UNREGISTER 6
#define MSG_NS_LOOKUP 7
#define MSG_NS_LOOKUPREPLY 8
#define MSG_NS_FAILURE 9
#define MSG_PING 10
#define MSG_PING_ACK 11
#define MSG_FAILURE 12
#define MSG_FAILURE_ACK 13
#define MSG_SHUTDOWN 99999
#define MSG_MON_ELECTION_ACK 15
#define MSG_MON_ELECTION_PROPOSE 16
#define MSG_MON_ELECTION_VICTORY 17
#define MSG_MON_OSDMAP_INFO 20
#define MSG_MON_OSDMAP_LEASE 21
#define MSG_MON_OSDMAP_LEASE_ACK 22
#define MSG_MON_OSDMAP_UPDATE_PREPARE 23
#define MSG_MON_OSDMAP_UPDATE_ACK 24
#define MSG_MON_OSDMAP_UPDATE_COMMIT 25
#define MSG_OSD_OP 40 // delete, etc.
#define MSG_OSD_OPREPLY 41 // delete, etc.
#define MSG_OSD_PING 42
#define MSG_OSD_GETMAP 43
#define MSG_OSD_MAP 44
#define MSG_OSD_BOOT 45
#define MSG_OSD_MKFS_ACK 46
#define MSG_OSD_FAILURE 47
#define MSG_OSD_IN 48
#define MSG_OSD_OUT 49
#define MSG_OSD_PG_NOTIFY 50
#define MSG_OSD_PG_QUERY 51
#define MSG_OSD_PG_SUMMARY 52
#define MSG_OSD_PG_LOG 53
#define MSG_OSD_PG_REMOVE 54
#define MSG_CLIENT_REQUEST 60
#define MSG_CLIENT_REPLY 61
//#define MSG_CLIENT_DONE 62
#define MSG_CLIENT_FILECAPS 63
#define MSG_CLIENT_INODEAUTHUPDATE 64
#define MSG_CLIENT_BOOT 70
#define MSG_CLIENT_MOUNT 71
#define MSG_CLIENT_MOUNTACK 72
#define MSG_CLIENT_UNMOUNT 73
// *** MDS ***
#define MSG_MDS_BOOT 100
#define MSG_MDS_GETMAP 101
#define MSG_MDS_MAP 102
#define MSG_MDS_HEARTBEAT 103
#define MSG_MDS_DISCOVER 110
#define MSG_MDS_DISCOVERREPLY 111
#define MSG_MDS_INODEGETREPLICA 112
#define MSG_MDS_INODEGETREPLICAACK 113
#define MSG_MDS_INODEFILECAPS 115
#define MSG_MDS_INODEUPDATE 120
#define MSG_MDS_DIRUPDATE 121
#define MSG_MDS_INODEEXPIRE 122
#define MSG_MDS_DIREXPIRE 123
#define MSG_MDS_DIREXPIREREQ 124
#define MSG_MDS_CACHEEXPIRE 125
#define MSG_MDS_ANCHORREQUEST 130
#define MSG_MDS_ANCHORREPLY 131
#define MSG_MDS_INODELINK 140
#define MSG_MDS_INODELINKACK 141
#define MSG_MDS_INODEUNLINK 142
#define MSG_MDS_INODEUNLINKACK 143
#define MSG_MDS_EXPORTDIRDISCOVER 150
#define MSG_MDS_EXPORTDIRDISCOVERACK 151
#define MSG_MDS_EXPORTDIRPREP 152
#define MSG_MDS_EXPORTDIRPREPACK 153
#define MSG_MDS_EXPORTDIRWARNING 154
#define MSG_MDS_EXPORTDIR 155
#define MSG_MDS_EXPORTDIRNOTIFY 156
#define MSG_MDS_EXPORTDIRNOTIFYACK 157
#define MSG_MDS_EXPORTDIRFINISH 158
#define MSG_MDS_HASHDIRDISCOVER 160
#define MSG_MDS_HASHDIRDISCOVERACK 161
#define MSG_MDS_HASHDIRPREP 162
#define MSG_MDS_HASHDIRPREPACK 163
#define MSG_MDS_HASHDIR 164
#define MSG_MDS_HASHDIRACK 165
#define MSG_MDS_HASHDIRNOTIFY 166
#define MSG_MDS_HASHREADDIR 168
#define MSG_MDS_HASHREADDIRREPLY 169
#define MSG_MDS_UNHASHDIRPREP 170
#define MSG_MDS_UNHASHDIRPREPACK 171
#define MSG_MDS_UNHASHDIR 172
#define MSG_MDS_UNHASHDIRACK 173
#define MSG_MDS_UNHASHDIRNOTIFY 174
#define MSG_MDS_UNHASHDIRNOTIFYACK 175
#define MSG_MDS_DENTRYUNLINK 200
#define MSG_MDS_RENAMEWARNING 300 // sent from src to bystanders
#define MSG_MDS_RENAMENOTIFY 301 // sent from dest to bystanders
#define MSG_MDS_RENAMENOTIFYACK 302 // sent back to src
#define MSG_MDS_RENAMEACK 303 // sent from src to initiator, to xlock_finish
#define MSG_MDS_RENAMEPREP 304 // sent from initiator to dest auth (if dir)
#define MSG_MDS_RENAMEREQ 305 // sent from initiator (or dest if dir) to src auth
#define MSG_MDS_RENAME 306 // sent from src to dest, includes inode
#define MSG_MDS_LOCK 500
#define MSG_MDS_SHUTDOWNSTART 900
#define MSG_MDS_SHUTDOWNFINISH 901
#include <stdlib.h>
#include <cassert>
#include <iostream>
#include <list>
using std::list;
#include <ext/hash_map>
#include <ext/rope>
using __gnu_cxx::crope;
#include "include/buffer.h"
#include "tcp.h"
// use fixed offsets and static entity -> logical addr mapping!
#define MSG_ADDR_NAMER_BASE 0
#define MSG_ADDR_RANK_BASE 1
#define MSG_ADDR_MDS_BASE 2
#define MSG_ADDR_OSD_BASE 3
#define MSG_ADDR_MON_BASE 4
#define MSG_ADDR_CLIENT_BASE 5
#define MSG_ADDR_NEW -1
// new typed msg_addr_t way!
class msg_addr_t {
public:
int _type;
int _num;
msg_addr_t() : _type(0), _num(0) {}
msg_addr_t(int t, int n) : _type(t), _num(n) {}
int num() const { return _num; }
int type() const { return _type; }
const char *type_str() const {
switch (type()) {
case MSG_ADDR_RANK_BASE: return "rank";
case MSG_ADDR_MDS_BASE: return "mds";
case MSG_ADDR_OSD_BASE: return "osd";
case MSG_ADDR_MON_BASE: return "mon";
case MSG_ADDR_CLIENT_BASE: return "client";
case MSG_ADDR_NAMER_BASE: return "namer";
}
return "unknown";
}
bool is_new() const { return num() == MSG_ADDR_NEW; }
bool is_client() const { return type() == MSG_ADDR_CLIENT_BASE; }
bool is_mds() const { return type() == MSG_ADDR_MDS_BASE; }
bool is_osd() const { return type() == MSG_ADDR_OSD_BASE; }
bool is_mon() const { return type() == MSG_ADDR_MON_BASE; }
bool is_namer() const { return type() == MSG_ADDR_NAMER_BASE; }
};
inline bool operator== (const msg_addr_t& l, const msg_addr_t& r) { return (l._type == r._type) && (l._num == r._num); }
inline bool operator!= (const msg_addr_t& l, const msg_addr_t& r) { return (l._type != r._type) || (l._num != r._num); }
inline bool operator< (const msg_addr_t& l, const msg_addr_t& r) { return (l._type < r._type) || (l._type == r._type && l._num < r._num); }
inline std::ostream& operator<<(std::ostream& out, const msg_addr_t& addr) {
//if (addr.is_namer()) return out << "namer";
if (addr.is_new() || addr.num() < 0)
return out << addr.type_str() << "?";
else
return out << addr.type_str() << addr.num();
}
namespace __gnu_cxx {
template<> struct hash< msg_addr_t >
{
size_t operator()( const msg_addr_t m ) const
{
static hash<int> H;
return H(m.type() ^ m.num());
}
};
}
#define MSG_ADDR_RANK(x) msg_addr_t(MSG_ADDR_RANK_BASE,x)
#define MSG_ADDR_MDS(x) msg_addr_t(MSG_ADDR_MDS_BASE,x)
#define MSG_ADDR_OSD(x) msg_addr_t(MSG_ADDR_OSD_BASE,x)
#define MSG_ADDR_MON(x) msg_addr_t(MSG_ADDR_MON_BASE,x)
#define MSG_ADDR_CLIENT(x) msg_addr_t(MSG_ADDR_CLIENT_BASE,x)
#define MSG_ADDR_NAMER(x) msg_addr_t(MSG_ADDR_NAMER_BASE,x)
#define MSG_ADDR_UNDEF msg_addr_t()
#define MSG_ADDR_DIRECTORY MSG_ADDR_NAMER(0)
#define MSG_ADDR_RANK_NEW MSG_ADDR_RANK(MSG_ADDR_NEW)
#define MSG_ADDR_MDS_NEW MSG_ADDR_MDS(MSG_ADDR_NEW)
#define MSG_ADDR_OSD_NEW MSG_ADDR_OSD(MSG_ADDR_NEW)
#define MSG_ADDR_CLIENT_NEW MSG_ADDR_CLIENT(MSG_ADDR_NEW)
#define MSG_ADDR_NAMER_NEW MSG_ADDR_NAMER(MSG_ADDR_NEW)
class entity_inst_t {
public:
tcpaddr_t addr;
__int64_t rank;
entity_inst_t() : rank(-1) {
memset(&addr, 0, sizeof(addr));
}
entity_inst_t(tcpaddr_t& a, int r) : addr(a), rank(r) {
memset(&addr, 0, sizeof(addr));
}
void set_addr(tcpaddr_t a) {
addr = a;
// figure out rank
rank = *((unsigned*)&a.sin_addr.s_addr);
rank |= (__uint64_t)a.sin_port << 32;
}
};
inline bool operator==(const entity_inst_t& a, const entity_inst_t& b) { return a.rank == b.rank && a.addr == b.addr; }
inline bool operator!=(const entity_inst_t& a, const entity_inst_t& b) { return !(a == b); }
inline bool operator>(const entity_inst_t& a, const entity_inst_t& b) { return a.rank > b.rank; }
inline bool operator>=(const entity_inst_t& a, const entity_inst_t& b) { return a.rank >= b.rank; }
inline bool operator<(const entity_inst_t& a, const entity_inst_t& b) { return a.rank < b.rank; }
inline bool operator<=(const entity_inst_t& a, const entity_inst_t& b) { return a.rank <= b.rank; }
inline ostream& operator<<(ostream& out, const entity_inst_t &i)
{
//return out << "rank" << i.rank << "_" << i.addr;
return out << i.addr;
}
// abstract Message class
typedef struct {
int type;
msg_addr_t source, dest;
entity_inst_t source_inst;
int source_port, dest_port;
int nchunks;
__uint64_t lamport_send_stamp;
__uint64_t lamport_recv_stamp;
} msg_envelope_t;
#define MSG_ENVELOPE_LEN sizeof(msg_envelope_t)
class Message {
private:
protected:
msg_envelope_t env; // envelope
bufferlist payload; // payload
friend class Messenger;
public:
public:
Message() {
env.source_port = env.dest_port = -1;
env.source = env.dest = MSG_ADDR_UNDEF;
env.nchunks = 0;
env.lamport_send_stamp = 0;
env.lamport_recv_stamp = 0;
};
Message(int t) {
env.source_port = env.dest_port = -1;
env.source = env.dest = MSG_ADDR_UNDEF;
env.nchunks = 0;
env.type = t;
env.lamport_send_stamp = 0;
env.lamport_recv_stamp = 0;
}
virtual ~Message() {
}
void set_lamport_send_stamp(__uint64_t t) { env.lamport_send_stamp = t; }
void set_lamport_recv_stamp(__uint64_t t) { env.lamport_recv_stamp = t; }
__uint64_t get_lamport_send_stamp() { return env.lamport_send_stamp; }
__uint64_t get_lamport_recv_stamp() { return env.lamport_recv_stamp; }
// for rpc-type procedural messages (pcid = procedure call id)
virtual long get_pcid() { return 0; }
virtual void set_pcid(long t) { assert(0); } // overload me
void clear_payload() { payload.clear(); }
bool empty_payload() { return payload.length() == 0; }
bufferlist& get_payload() {
return payload;
}
void set_payload(bufferlist& bl) {
payload.claim(bl);
}
msg_envelope_t& get_envelope() {
return env;
}
void set_envelope(msg_envelope_t& env) {
this->env = env;
}
// ENVELOPE ----
// type
int get_type() { return env.type; }
void set_type(int t) { env.type = t; }
virtual char *get_type_name() = 0;
// source/dest
msg_addr_t& get_dest() { return env.dest; }
void set_dest(msg_addr_t a, int p) { env.dest = a; env.dest_port = p; }
int get_dest_port() { return env.dest_port; }
msg_addr_t& get_source() { return env.source; }
void set_source(msg_addr_t a, int p) { env.source = a; env.source_port = p; }
int get_source_port() { return env.source_port; }
entity_inst_t& get_source_inst() { return env.source_inst; }
void set_source_inst(const entity_inst_t &i) { env.source_inst = i; }
// PAYLOAD ----
void reset_payload() {
payload.clear();
}
// overload either the rope version (easier!)
virtual void encode_payload(crope& s) { assert(0); }
virtual void decode_payload(crope& s, int& off) { assert(0); }
// of the bufferlist versions (faster!)
virtual void decode_payload() {
// use a crope for convenience, small messages, etc. FIXME someday.
crope ser;
for (list<bufferptr>::const_iterator it = payload.buffers().begin();
it != payload.buffers().end();
it++)
ser.append((*it).c_str(), (*it).length());
int off = 0;
decode_payload(ser, off);
assert((unsigned)off == payload.length());
}
virtual void encode_payload() {
assert(payload.length() == 0); // caller should reset payload
// use crope for convenience, small messages. FIXME someday.
crope r;
encode_payload(r);
// copy payload
payload.push_back( buffer::copy(r.c_str(), r.length()) );
}
virtual void print(ostream& out) {
out << get_type_name();
}
};
extern Message *decode_message(msg_envelope_t &env, bufferlist& bl);
inline ostream& operator<<(ostream& out, Message& m) {
m.print(out);
return out;
}
#endif