mount_ceph_SOURCES = mount/mount.ceph.c
sbin_PROGRAMS += mount.ceph
+
+ core: cmon cosd cmds mkmonfs ceph cconf monmaptool osdmaptool crushtool
+
+
dumpjournal_SOURCES = dumpjournal.cc msg/SimpleMessenger.cc
-dumpjournal_LDADD = libosdc.a libcrush.a libcommon.a
+dumpjournal_LDADD = libosdc.a libcrush.a libcommon.a -lcrypto
dupstore_SOURCES = dupstore.cc
-dupstore_LDADD = libos.a libcommon.a
+dupstore_LDADD = libos.a libcommon.a -lcrypto
streamtest_SOURCES = streamtest.cc
-streamtest_LDADD = libos.a libcommon.a
+streamtest_LDADD = libos.a libcommon.a -lcrypto
bin_PROGRAMS += dumpjournal dupstore streamtest
# synthetic client
--- /dev/null
- bool ms_handle_reset(Connection *con, const entity_addr_t& peer) { return false; }
- void ms_handle_failure(Connection *con, Message *m, const entity_addr_t& peer) { }
- void ms_handle_remote_reset(Connection *con, const entity_addr_t& peer) {}
+// -*- 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) 2004-2009 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 __AUTHORIZESERVER_H
+#define __AUTHORIZESERVER_H
+
+#include "config.h"
+
+#include "msg/SimpleMessenger.h"
+
+class Messenger;
+class KeysKeeper;
+class Message;
+class MAuthorize;
+
+class AuthorizeServer : public Dispatcher {
+ Messenger *messenger;
+
+ bool _dispatch(Message *m);
+ bool ms_dispatch(Message *m);
+
++ bool ms_handle_reset(Connection *con) { return false; }
++ void ms_handle_remote_reset(Connection *con) {}
+
+ KeysKeeper *keys;
+
+ Mutex lock;
+
+ int do_authorize(bufferlist::iterator& indata, bufferlist& result_bl);
+ void build_cephx_response_header(int request_type, int status, bufferlist& bl);
+public:
+ AuthorizeServer(Messenger *m, KeysKeeper *k) : messenger(m), keys(k), lock("auth_server") {}
+ ~AuthorizeServer();
+
+ bool init();
+ void handle_request(MAuthorize *m);
+ int verify_authorizer(int peer_type, bufferlist::iterator& indata, bufferlist& result_bl);
+};
+
+#endif
break;
}
+ case PAXOS_AUTH:
+ {
+ bufferlist::iterator p = notify->bl.begin();
+ if (notify->is_latest) {
+ KeysServerData data;
+ ::decode(data, p);
+ dout(0) << " auth " << dendl;
+#if 0
+ // show the first class info
+ map<EntityName, CryptoKey>::iterator mapiter = list.keys.secrets_begin();
+ if (mapiter != list.keys.secrets_end()) {
+ dout(0) << " auth " << mapiter->first.to_str() << dendl;
+ }
+#endif
+ } else {
+ AuthLibEntry entry;
+
+ while (!p.end()) {
+ entry.decode(p);
+ dout(0) << " auth " << entry.name.to_str() << dendl;
+ }
+ }
+ break;
+ }
++
+ case PAXOS_MONMAP:
+ {
+ mc.monmap.decode(notify->bl);
+ dout(0) << " mon " << mc.monmap << dendl;
+ }
+ break;
+
+ default:
+ dout(0) << " ignoring unknown machine id " << notify->machine_id << dendl;
}
map_ver[notify->machine_id] = notify->ver;
__le32 fl_pg_pool; /* namespace, crush ruleset, rep level */
} __attribute__ ((packed));
- #define CEPH_DEFAULT_OBJECT_SIZE 2<<22
- #define CEPH_DEFAULT_STRIPE_COUNT 1
+ #define CEPH_MIN_STRIPE_UNIT 65536
+ int ceph_file_layout_is_valid(const struct ceph_file_layout *layout);
+/*
+ * An encryption key/secret.
+ */
+struct ceph_secret {
+ __le16 type;
+ __le64 timestamp;
+ __le16 len;
+ char key[];
+} __attribute__ ((packed));
+
+#define CEPH_SECRET_NONE 0x0
+#define CEPH_SECRET_AES 0x1
+
+
/*********************************************
* message layer
*/
#define CEPH_MSG_STATFS_REPLY 14
#define CEPH_MSG_MON_SUBSCRIBE 15
#define CEPH_MSG_MON_SUBSCRIBE_ACK 16
+#define CEPH_MSG_AUTH 17
+#define CEPH_MSG_AUTHORIZE 18
+#define CEPH_MSG_AUTH_REPLY 19
/* client <-> mds */
- #define CEPH_MSG_MDS_GETMAP 20
#define CEPH_MSG_MDS_MAP 21
#define CEPH_MSG_CLIENT_SESSION 22
#define CEPH_MSG_OSD_OP 42
#define CEPH_MSG_OSD_OPREPLY 43
-
+/* auth */
- struct ceph_mon_statfs {
+#define CEPH_AUTH_NONE 0
+#define CEPH_AUTH_CEPH 1
+
+struct ceph_auth_type {
+ __le32 type;
+} __attribute__ ((packed));
+
+ struct ceph_mon_request_header {
__le64 have_version;
+ __le16 session_mon;
+ __le64 session_mon_tid;
+ } __attribute__ ((packed));
+
+ struct ceph_mon_statfs {
+ struct ceph_mon_request_header monhdr;
struct ceph_fsid fsid;
__le64 tid;
} __attribute__ ((packed));
struct ceph_statfs st;
} __attribute__ ((packed));
+struct ceph_mon_auth_req_hdr {
+ __le64 have_version;
+} __attribute__ ((packed));
+
+struct ceph_mon_auth_init_req {
+ __le32 num_auth;
+ struct ceph_auth_type auth_type[0];
+} __attribute__ ((packed));
+
+struct ceph_mon_auth_reply_hdr {
+ __le32 status;
+} __attribute__ ((packed));
+
+struct ceph_mon_auth_x_reply {
+ __le64 server_challenge;
+} __attribute__ ((packed));
+
+struct ceph_mon_auth_x_request {
+ __le64 client_challenge;
+} __attribute__ ((packed));
+
struct ceph_osd_getmap {
- __le64 have_version;
+ struct ceph_mon_request_header monhdr;
struct ceph_fsid fsid;
__le32 start;
} __attribute__ ((packed));
--- /dev/null
- common_init(args, "libceph", false);
+ #include "client/libceph.h"
+
+ #include <string.h>
+ #include <fcntl.h>
+ #include <iostream>
+
+ #include "common/Mutex.h"
+ #include "messages/MMonMap.h"
+ #include "common/common_init.h"
+ #include "msg/SimpleMessenger.h"
+ #include "client/Client.h"
+
+ /* ************* ************* ************* *************
+ * C interface
+ */
+
+ extern "C" const char *ceph_version(int *major, int *minor, int *patch)
+ {
+ if (major)
+ *major = CEPH_VERSION_MAJOR;
+ if (minor)
+ *minor = CEPH_VERSION_MINOR;
+ if (patch)
+ *patch = CEPH_VERSION_PATCH;
+ return CEPH_VERSION;
+ }
+
+ static Mutex ceph_client_mutex("ceph_client");
+ static int client_initialized = 0;
+ static int client_mount = 0;
+ static Client *client = NULL;
+ static MonClient *monclient = NULL;
+ static SimpleMessenger *rank = NULL;
+
+ extern "C" int ceph_initialize(int argc, const char **argv)
+ {
+ ceph_client_mutex.Lock();
+ if (!client_initialized) {
+ //create everything to start a client
+ vector<const char*> args;
+ argv_to_vec(argc, argv, args);
++ common_init(args, "libceph", false, true);
+ if (g_conf.clock_tare) g_clock.tare();
+ //monmap
+ monclient = new MonClient();
+ if (monclient->build_initial_monmap() < 0) {
+ delete monclient;
+ return -1; //error!
+ }
+ //network connection
+ rank = new SimpleMessenger();
+
+ //at last the client
+ client = new Client(rank->register_entity(entity_name_t::CLIENT()), monclient);
+
+ rank->start();
+
+ client->init();
+ }
+ ++client_initialized;
+ ceph_client_mutex.Unlock();
+ return 0;
+ }
+
+ extern "C" void ceph_deinitialize()
+ {
+ ceph_client_mutex.Lock();
+ --client_initialized;
+ if(!client_initialized) {
+ client->unmount();
+ client->shutdown();
+ delete client;
+ rank->wait();
+ delete rank;
+ delete monclient;
+ }
+ ceph_client_mutex.Unlock();
+ }
+
+ extern "C" int ceph_mount()
+ {
+ int ret;
+ Mutex::Locker lock(ceph_client_mutex);
+ if(!client_mount) {
+ ret = client->mount();
+ if (ret!=0)
+ return ret;
+ }
+ ++client_mount;
+ return 0;
+ }
+
+ extern "C" int ceph_umount()
+ {
+ Mutex::Locker lock(ceph_client_mutex);
+ --client_mount;
+ if (!client_mount)
+ return client->unmount();
+ return 0;
+ }
+
+ extern "C" int ceph_statfs(const char *path, struct statvfs *stbuf)
+ {
+ return client->statfs(path, stbuf);
+ }
+
+ extern "C" int ceph_get_local_osd()
+ {
+ return client->get_local_osd();
+ }
+
+ extern "C" int ceph_getcwd(char *buf, int buflen)
+ {
+ string cwd;
+ client->getcwd(cwd);
+ int size = cwd.size()+1; //need space for null character
+ if (size > buflen) {
+ if (buflen == 0) return size;
+ else return -ERANGE;
+ }
+ size = cwd.copy(buf, size);
+ buf[size] = '\0'; //fill in null character
+ return 0;
+ }
+
+ extern "C" int ceph_chdir (const char *s)
+ {
+ return client->chdir(s);
+ }
+
+ /*if we want to extern C this, we need to convert it to const char*,
+ which will mean storing it somewhere or else making the caller
+ responsible for delete-ing a c-string they didn't create*/
+ void ceph_getcwd(string& cwd)
+ {
+ client->getcwd(cwd);
+ }
+
+ extern "C" int ceph_opendir(const char *name, DIR **dirpp)
+ {
+ return client->opendir(name, dirpp);
+ }
+
+ extern "C" int ceph_closedir(DIR *dirp)
+ {
+ return client->closedir(dirp);
+ }
+
+ extern "C" int ceph_readdir_r(DIR *dirp, struct dirent *de)
+ {
+ return client->readdir_r(dirp, de);
+ }
+
+ extern "C" int ceph_readdirplus_r(DIR *dirp, struct dirent *de, struct stat *st, int *stmask)
+ {
+ return client->readdirplus_r(dirp, de, st, stmask);
+ }
+
+ extern "C" int ceph_getdents(DIR *dirp, char *buf, int buflen)
+ {
+ return client->getdents(dirp, buf, buflen);
+ }
+
+ extern "C" int ceph_getdnames(DIR *dirp, char *buf, int buflen)
+ {
+ return client->getdnames(dirp, buf, buflen);
+ }
+
+ extern "C" void ceph_rewinddir(DIR *dirp)
+ {
+ client->rewinddir(dirp);
+ }
+
+ extern "C" loff_t ceph_telldir(DIR *dirp)
+ {
+ return client->telldir(dirp);
+ }
+
+ extern "C" void ceph_seekdir(DIR *dirp, loff_t offset)
+ {
+ client->seekdir(dirp, offset);
+ }
+
+ extern "C" int ceph_link (const char *existing, const char *newname)
+ {
+ return client->link(existing, newname);
+ }
+
+ extern "C" int ceph_unlink (const char *path)
+ {
+ return client->unlink(path);
+ }
+
+ extern "C" int ceph_rename(const char *from, const char *to)
+ {
+ return client->rename(from, to);
+ }
+
+ // dirs
+ extern "C" int ceph_mkdir(const char *path, mode_t mode)
+ {
+ return client->mkdir(path, mode);
+ }
+
+ extern "C" int ceph_mkdirs(const char *path, mode_t mode)
+ {
+ return client->mkdirs(path, mode);
+ }
+
+ extern "C" int ceph_rmdir(const char *path)
+ {
+ return client->rmdir(path);
+ }
+
+ // symlinks
+ extern "C" int ceph_readlink(const char *path, char *buf, loff_t size)
+ {
+ return client->readlink(path, buf, size);
+ }
+
+ extern "C" int ceph_symlink(const char *existing, const char *newname)
+ {
+ return client->symlink(existing, newname);
+ }
+
+ // inode stuff
+ extern "C" int ceph_lstat(const char *path, struct stat *stbuf)
+ {
+ return client->lstat(path, stbuf);
+ }
+
+ extern "C" int ceph_lstat_precise(const char *path, stat_precise *stbuf)
+ {
+ return client->lstat_precise(path, (Client::stat_precise*)stbuf);
+ }
+
+ extern "C" int ceph_setattr(const char *relpath, struct stat *attr, int mask)
+ {
+ Client::stat_precise p_attr = Client::stat_precise(*attr);
+ return client->setattr(relpath, &p_attr, mask);
+ }
+
+ extern "C" int ceph_setattr_precise(const char *relpath,
+ struct stat_precise *attr, int mask) {
+ return client->setattr(relpath, (Client::stat_precise*)attr, mask);
+ }
+
+ extern "C" int ceph_chmod(const char *path, mode_t mode)
+ {
+ return client->chmod(path, mode);
+ }
+ extern "C" int ceph_chown(const char *path, uid_t uid, gid_t gid)
+ {
+ return client->chown(path, uid, gid);
+ }
+
+ extern "C" int ceph_utime(const char *path, struct utimbuf *buf)
+ {
+ return client->utime(path, buf);
+ }
+
+ extern "C" int ceph_truncate(const char *path, loff_t size)
+ {
+ return client->truncate(path, size);
+ }
+
+ // file ops
+ extern "C" int ceph_mknod(const char *path, mode_t mode, dev_t rdev)
+ {
+ return client->mknod(path, mode, rdev);
+ }
+
+ extern "C" int ceph_open(const char *path, int flags, mode_t mode)
+ {
+ return client->open(path, flags, mode);
+ }
+
+ extern "C" int ceph_close(int fd)
+ {
+ return client->close(fd);
+ }
+
+ extern "C" loff_t ceph_lseek(int fd, loff_t offset, int whence)
+ {
+ return client->lseek(fd, offset, whence);
+ }
+
+ extern "C" int ceph_read(int fd, char *buf, loff_t size, loff_t offset)
+ {
+ return client->read(fd, buf, size, offset);
+ }
+
+ extern "C" int ceph_write(int fd, const char *buf, loff_t size, loff_t offset)
+ {
+ return client->write(fd, buf, size, offset);
+ }
+
+ extern "C" int ceph_ftruncate(int fd, loff_t size)
+ {
+ return client->ftruncate(fd, size);
+ }
+
+ extern "C" int ceph_fsync(int fd, bool syncdataonly)
+ {
+ return client->fsync(fd, syncdataonly);
+ }
+
+ extern "C" int ceph_fstat(int fd, struct stat *stbuf)
+ {
+ return client->fstat(fd, stbuf);
+ }
+
+ extern "C" int ceph_sync_fs()
+ {
+ return client->sync_fs();
+ }
+
+ extern "C" int ceph_get_file_stripe_unit(int fh)
+ {
+ return client->get_file_stripe_unit(fh);
+ }
+
+ extern "C" int ceph_get_file_replication(const char *path) {
+ int fd = client->open(path, O_RDONLY);
+ int rep = client->get_file_replication(fd);
+ client->close(fd);
+ return rep;
+ }
+
+ extern "C" int ceph_get_default_preferred_pg(int fd)
+ {
+ return client->get_default_preferred_pg(fd);
+ }
+
+ extern "C" int ceph_set_default_file_stripe_unit(int stripe)
+ {
+ client->set_default_file_stripe_unit(stripe);
+ return 0;
+ }
+
+ extern "C" int ceph_set_default_file_stripe_count(int count)
+ {
+ client->set_default_file_stripe_unit(count);
+ return 0;
+ }
+
+ extern "C" int ceph_set_default_object_size(int size)
+ {
+ client->set_default_object_size(size);
+ return 0;
+ }
+
+ extern "C" int ceph_set_default_file_replication(int replication)
+ {
+ client->set_default_file_replication(replication);
+ return 0;
+ }
+
+ extern "C" int ceph_set_default_preferred_pg(int pg)
+ {
+ client->set_default_preferred_pg(pg);
+ return 0;
+ }
+
+ extern "C" int ceph_get_file_stripe_address(int fh, loff_t offset, char *buf, int buflen)
+ {
+ string address;
+ int r = client->get_file_stripe_address(fh, offset, address);
+ if (r != 0) return r; //at time of writing, method ONLY returns
+ // 0 or -EINVAL if there are no known osds
+ int len = address.size()+1;
+ if (len > buflen) {
+ if (buflen == 0) return len;
+ else return -ERANGE;
+ }
+ len = address.copy(buf, len, 0);
+ buf[len] = '\0'; // write a null char to terminate c-style string
+ return 0;
+ }
bool _dispatch(Message *m);
bool ms_dispatch(Message *m);
- bool ms_handle_reset(Connection *con, const entity_addr_t& peer);
- void ms_handle_failure(Connection *con, Message *m, const entity_addr_t& peer) { }
- void ms_handle_remote_reset(Connection *con, const entity_addr_t& peer);
+ bool ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new) {
+ dout(0) << "RadosClient::ms_get_authorizer type=" << dest_type << dendl;
+ uint32_t want = peer_id_to_entity_type(dest_type);
+ if (monclient.auth.build_authorizer(want, authorizer) < 0)
+ return false;
+
+ return true;
+ }
+ void ms_handle_connect(Connection *con);
+ bool ms_handle_reset(Connection *con);
+ void ms_handle_remote_reset(Connection *con);
+
+
Objecter *objecter;
Mutex lock;
messenger->add_dispatcher_head(this);
- rank.set_policy(entity_name_t::TYPE_MON, SimpleMessenger::Policy::lossy_fail_after(1.0));
- rank.set_policy(entity_name_t::TYPE_MDS, SimpleMessenger::Policy::lossless());
- rank.set_policy(entity_name_t::TYPE_OSD, SimpleMessenger::Policy::lossless());
- rank.set_policy(entity_name_t::TYPE_CLIENT, SimpleMessenger::Policy::lossless()); // mds does its own timeout/markdown
-
rank.start(1);
+ messenger->add_dispatcher_head(this);
+
+ monclient.set_want_keys(CEPHX_PRINCIPAL_MON | CEPHX_PRINCIPAL_OSD);
+ monclient.init();
+
+ if (monclient.get_monmap() < 0)
+ return false;
+
+ monclient.wait_authenticate(30.0);
+
+ monclient.mount(g_conf.client_mount_timeout);
objecter = new Objecter(messenger, &monclient, &osdmap, lock);
if (!objecter)
_finish_hunting();
- // monmap
- bufferlist::iterator p = m->monmap_bl.begin();
- ::decode(monmap, p);
+ if (m->result) {
+ mount_err = m->result;
+ dout(0) << "mount error " << m->result << " (" << m->result_msg << ")" << dendl;
+ } else {
+ // monmap
+ bufferlist::iterator p = m->monmap_bl.begin();
+ ::decode(monmap, p);
- clientid = m->client;
- messenger->set_myname(entity_name_t::CLIENT(m->client.v));
+ clientid = m->client;
+ messenger->set_myname(entity_name_t::CLIENT(m->client.v));
+ }
mount_cond.SignalAll();
-
delete m;
}
}
}
- bool MonClient::ms_handle_reset(Connection *con, const entity_addr_t& peer)
+void MonClient::_reopen_session()
+{
+ dout(10) << "_reopen_session" << dendl;
+ if (state != MC_STATE_HAVE_SESSION) {
+ state = MC_STATE_NONE;
+ auth_handler.reset();
+ authorize_handler.reset();
+ }
+ _pick_new_mon();
+ _open_session();
+}
+
+
+ bool MonClient::ms_handle_reset(Connection *con)
{
- dout(10) << "ms_handle_reset " << peer << dendl;
- if (hunting)
- return true;
+ Mutex::Locker lock(monc_lock);
- dout(0) << "hunting for new mon" << dendl;
- hunting = true;
- _reopen_session();
+ if (con->get_peer_type() == CEPH_ENTITY_TYPE_MON) {
+ if (con->get_peer_addr() != monmap.get_inst(cur_mon).addr) {
+ dout(10) << "ms_handle_reset stray mon " << con->get_peer_addr() << dendl;
+ return true;
+ } else {
+ dout(10) << "ms_handle_reset current mon " << con->get_peer_addr() << dendl;
+ if (hunting)
+ return true;
+
+ dout(0) << "hunting for new mon" << dendl;
+ hunting = true;
+ _reopen_session();
+ }
+ }
return false;
}
if (now > sub_renew_after)
_renew_subs();
- int oldmon = monmap.pick_mon();
- messenger->send_keepalive(monmap.mon_inst[oldmon]);
+ messenger->send_keepalive(monmap.mon_inst[cur_mon]);
}
+ auth.tick();
+
timer.add_event_after(10.0, new C_Tick(this));
}
classmon()->dispatch(m);
return;
}
- if (m->cmd[0] == "mon") {
- if (m->cmd[1] == "injectargs" && m->cmd.size() == 4) {
- vector<string> args(2);
- args[0] = "_injectargs";
- args[1] = m->cmd[3];
- if (m->cmd[2] == "*") {
- for (unsigned i=0; i<monmap->size(); i++)
- inject_args(monmap->get_inst(i), args, 0);
- r = 0;
- rs = "ok bcast";
- } else {
- errno = 0;
- int who = strtol(m->cmd[2].c_str(), 0, 10);
- if (!errno && who >= 0) {
- inject_args(monmap->get_inst(who), args, 0);
- r = 0;
- rs = "ok";
- } else
- rs = "specify mon number or *";
- }
- } else
- rs = "unrecognized mon command";
- } else
- rs = "unrecognized subsystem";
+ if (m->cmd[0] == "auth") {
+ authmon()->dispatch(m);
+ return;
+ }
+ rs = "unrecognized subsystem";
} else
rs = "no command";
Session *s = (Session *)con->get_priv();
if (!s)
return false;
-
+
Mutex::Locker l(lock);
-
+
dout(10) << "reset/close on session " << s->inst << dendl;
- session_map.remove_session(s);
+ remove_session(s);
s->put();
+
+ // remove from connection, too.
+ con->set_priv(NULL);
return true;
}
while (!p.end()) {
Session *s = *p;
++p;
- if (!s->until.is_zero() && (s->until < now)) {
- dout(10) << " trimming session " << s->inst << " (until " << s->until << " < now " << now << ")" << dendl;
+
+ // don't trim monitors
+ if (s->inst.name.is_mon())
+ continue;
+
- if (s->until < now) {
- dout(10) << " trimming session " << s->inst << " (until " << s->until << " < now " << now << ")" << dendl;
++ if (!s->until.is_zero() && s->until < now) {
++ dout(10) << " trimming session " << s->inst
++ << " (until " << s->until << " < now " << now << ")" << dendl;
messenger->mark_down(s->inst.addr);
- session_map.remove_session(s);
+ remove_session(s);
}
}
}
}
- void Monitor::handle_route(MRoute *m)
- {
- dout(10) << "handle_route " << *m->msg << " to " << m->dest << dendl;
-
- messenger->send_message(m->msg, m->dest);
- m->msg = NULL;
- delete m;
- }
-
+bool Monitor::ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new)
+{
+ AuthServiceTicketInfo auth_ticket_info;
+
+ SessionAuthInfo info;
+ int ret;
+ uint32_t service_id = peer_id_to_entity_type(dest_type);
+
+ dout(0) << "ms_get_authorizer service_id=" << service_id << dendl;
+
+ if (service_id != CEPHX_PRINCIPAL_MON) {
+ ret = keys_server.build_session_auth_info(service_id, auth_ticket_info, info);
+ if (ret < 0) {
+ return false;
+ }
+ } else {
+ EntityName name;
+ name.entity_type = CEPHX_PRINCIPAL_MON;
+
+ CryptoKey secret;
+ if (!keys_server.get_secret(name, secret)) {
+ dout(0) << "couldn't get secret for mon service!" << dendl;
+ stringstream ss;
+ keys_server.list_secrets(ss);
+ dout(0) << ss.str() << dendl;
+ return false;
+ }
+ /* mon to mon authentication uses the private monitor shared key and not the
+ rotating key */
+ ret = keys_server.build_session_auth_info(service_id, auth_ticket_info, info, secret, (uint64_t)-1);
+ if (ret < 0) {
+ return false;
+ }
+ dout(0) << "built session auth_info for use with mon" << dendl;
+
+ }
+
+ bufferlist ticket_data;
+ ret = build_service_ticket(info, ticket_data);
+ if (ret < 0)
+ return false;
+
+ dout(0) << "built service ticket" << dendl;
+ bufferlist::iterator iter = ticket_data.begin();
+ AuthTicketHandler handler;
+ ::decode(handler.ticket, iter);
+
+ handler.service_id = service_id;
+ handler.session_key = info.session_key;
+
+ AuthContext ctx;
+ handler.build_authorizer(authorizer, ctx);
+
+ return true;
+}
+
+bool Monitor::ms_verify_authorizer(Connection *con, int peer_type,
+ bufferlist& authorizer_data, bufferlist& authorizer_reply,
+ bool& isvalid)
+{
+ dout(0) << "Monitor::verify_authorizer start" << dendl;
+
+ bufferlist::iterator iter = authorizer_data.begin();
+
+ isvalid = true;
+
+ if (!authorizer_data.length())
+ return true; /* we're not picky */
+
+ int ret = authorizer.verify_authorizer(peer_type, iter, authorizer_reply);
+ dout(0) << "Monitor::verify_authorizer returns " << ret << dendl;
+
+ isvalid = (ret >= 0);
+
+ return true;
+};
private:
bool ms_dispatch(Message *m);
- bool ms_handle_reset(Connection *con, const entity_addr_t& peer);
- void ms_handle_failure(Connection *con, Message *m, const entity_addr_t& peer) { }
- void ms_handle_remote_reset(Connection *con, const entity_addr_t& peer) {}
+ bool ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new);
+ bool ms_verify_authorizer(Connection *con, int peer_type,
+ bufferlist& authorizer_data, bufferlist& authorizer_reply,
+ bool& isvalid);
+ bool ms_handle_reset(Connection *con);
+ void ms_handle_remote_reset(Connection *con) {}
public:
Monitor(int w, MonitorStore *s, Messenger *m, MonMap *map);
#define PAXOS_CLIENTMAP 3
#define PAXOS_LOG 4
#define PAXOS_CLASS 5
- #define PAXOS_AUTH 6
- #define PAXOS_NUM 7
+ #define PAXOS_MONMAP 6
-#define PAXOS_NUM 7
++#define PAXOS_AUTH 7
++#define PAXOS_NUM 8
inline const char *get_paxos_name(int p) {
switch (p) {
// on deliberate reset of connection by remote
// implies incoming messages dropped; possibly/probably some of our previous outgoing too.
- virtual void ms_handle_remote_reset(Connection *con, const entity_addr_t& peer) = 0;
-
+ virtual void ms_handle_remote_reset(Connection *con) = 0;
+
+ // authorization handshake provides mutual authentication of peers.
+ // connecting side
+ virtual bool ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new) { return false; };
+ // accepting side
+ virtual bool ms_verify_authorizer(Connection *con, int peer_type,
+ bufferlist& authorizer, bufferlist& authorizer_reply,
+ bool& isvalid) { return false; };
};
#endif
for (list<Dispatcher*>::iterator p = dispatchers.begin();
p != dispatchers.end();
p++)
- (*p)->ms_handle_failure(con, m, peer);
+ (*p)->ms_handle_remote_reset(con);
}
+ bool ms_deliver_get_authorizer(int peer_type, bufferlist& authorizer, bool force_new) {
+ for (list<Dispatcher*>::iterator p = dispatchers.begin();
+ p != dispatchers.end();
+ p++)
+ if ((*p)->ms_get_authorizer(peer_type, authorizer, force_new))
+ return true;
+ return false;
+ }
+ bool ms_deliver_verify_authorizer(Connection *con, int peer_type,
+ bufferlist& authorizer, bufferlist& authorizer_reply, bool& isvalid) {
+ for (list<Dispatcher*>::iterator p = dispatchers.begin();
+ p != dispatchers.end();
+ p++)
+ if ((*p)->ms_verify_authorizer(con, peer_type, authorizer, authorizer_reply, isvalid))
+ return true;
+ return false;
+ }
+
// shutdown
virtual int shutdown() = 0;
virtual void suicide() = 0;
connect.global_seq = gseq;
connect.connect_seq = cseq;
connect.protocol_version = get_proto_version(rank->my_type, peer_type, true);
+ connect.authorizer_len = authorizer.length();
+ dout(0) << "connect.authorizer_len=" << connect.authorizer_len << dendl;
connect.flags = 0;
- if (policy.lossy_tx)
- connect.flags |= CEPH_MSG_CONNECT_LOSSY;
+ if (policy.lossy)
+ connect.flags |= CEPH_MSG_CONNECT_LOSSY; // this is fyi, actually, server decides!
memset(&msg, 0, sizeof(msg));
msgvec[0].iov_base = (char*)&connect;
msgvec[0].iov_len = sizeof(connect);
return ++global_seq;
}
- void set_addr(entity_addr_t a) {
- rank_addr = a;
- need_addr = false;
- }
-
+ bool get_authorizer(int peer_type, bufferlist& bl, bool force_new);
+ bool verify_authorizer(Connection *con, int peer_type, bufferlist& auth, bufferlist& auth_reply,
+ bool& isvalid);
+
Endpoint *register_entity(entity_name_t addr);
void rename_entity(Endpoint *ms, entity_name_t newaddr);
void unregister_entity(Endpoint *ms);
monc->sub_want("monmap", 0);
monc->renew_subs();
+ monc->wait_authenticate(30.0);
+ monc->wait_auth_rotating(30.0);
// announce to monitor i exist and have booted.
- do_mon_report();
+ send_boot();
op_tp.start();
recovery_tp.start();
private:
bool ms_dispatch(Message *m);
- bool ms_handle_reset(Connection *con, const entity_addr_t& peer) { return false; }
- void ms_handle_failure(Connection *con, Message *m, const entity_addr_t& peer) { }
- void ms_handle_remote_reset(Connection *con, const entity_addr_t& peer) {}
+ bool ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new);
+ bool ms_verify_authorizer(Connection *con, int peer_type,
+ bufferlist& authorizer, bufferlist& authorizer_reply,
+ bool& isvalid);
-
+ void ms_handle_connect(Connection *con);
+ bool ms_handle_reset(Connection *con) { return false; }
+ void ms_handle_remote_reset(Connection *con) {}
public:
OSD(int id, Messenger *m, Messenger *hbm, MonClient *mc, const char *dev = 0, const char *jdev = 0);