tools/cephfs/Resetter.h \
tools/cephfs/Dumper.h \
tools/cephfs/MDSUtility.h \
- tools/rados/rados_sync.h \
- tools/common.h
+ tools/rados/rados_sync.h
+++ /dev/null
-// -*- 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-2010 Sage Weil <sage@newdream.net>
- * Copyright (C) 2010 Dreamhost
- *
- * 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 <limits.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <iostream>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <vector>
-#include <sys/socket.h>
-#include <linux/un.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "common/ceph_argparse.h"
-#include "global/global_init.h"
-#include "common/errno.h"
-#include "common/safe_io.h"
-#include "common/config.h"
-#include "tools/common.h"
-
-#include "include/compat.h"
-#include "include/assert.h"
-
-using std::vector;
-
-void do_status(CephToolCtx *ctx, bool shutdown = false);
-
-static void usage()
-{
- cout << "usage:\n";
- cout << " ceph [options] [command]\n";
- cout << " ceph -s cluster status summary\n";
- cout << " ceph -w running cluster summary and events\n";
- cout << "\n";
- cout << "If no commands are specified, enter interactive mode.\n";
- cout << "\n";
- cout << "CLUSTER COMMANDS\n";
- cout << " ceph health [detail]\n";
- cout << " ceph quorum_status\n";
- cout << " ceph df [detail]\n";
- cout << " ceph -m <mon-ip-or-host> mon_status\n";
- cout << "\n";
- cout << "AUTHENTICATION (AUTH) COMMANDS\n";
- cout << " ceph auth get-or-create[-key] <name> [capsys1 capval1 [...]]\n";
- cout << " ceph auth del <name>\n";
- cout << " ceph auth list\n";
- cout << "\n";
- cout << "METADATA SERVER (MDS) COMMANDS\n";
- cout << " ceph mds stat\n";
- cout << " ceph mds tell <mds-id or *> injectargs '--<switch> <value> [--<switch> <value>...]'\n";
- cout << " ceph mds add_data_pool <pool-id>\n";
- cout << "\n";
- cout << "MONITOR (MON) COMMANDS\n";
- cout << " ceph mon add <name> <ip>[:<port>]\n";
- cout << " ceph mon remove <name>\n";
- cout << " ceph mon stat\n";
- cout << " ceph mon tell <mon-id or *> injectargs '--<switch> <value> [--<switch> <value>...]'\n";
- cout << "\n";
- cout << "OBJECT STORAGE DEVICE (OSD) COMMANDS\n";
- cout << " ceph osd dump [--format=json]\n";
- cout << " ceph osd ls [--format=json]\n";
- cout << " ceph osd tree\n";
- cout << " ceph osd map <pool-name> <object-name>\n";
- cout << " ceph osd down <osd-id>\n";
- cout << " ceph osd in <osd-id>\n";
- cout << " ceph osd out <osd-id>\n";
- cout << " ceph osd set <noout|noin|nodown|noup|noscrub|nodeep-scrub>\n";
- cout << " ceph osd unset <noout|noin|nodown|noup|noscrub|nodeep-scrub>\n";
- cout << " ceph osd pause\n";
- cout << " ceph osd unpause\n";
- cout << " ceph osd tell <osd-id or *> injectargs '--<switch> <value> [--<switch> <value>...]'\n";
- cout << " ceph osd getcrushmap -o <file>\n";
- cout << " ceph osd getmap -o <file>\n";
- cout << " ceph osd crush set <osd-id> <weight> <loc1> [<loc2> ...]\n";
- cout << " ceph osd crush add <osd-id> <weight> <loc1> [<loc2> ...]\n";
- cout << " ceph osd crush create-or-move <osd-id> <initial-weight> <loc1> [<loc2> ...]\n";
- cout << " ceph osd crush rm <name> [ancestor]\n";
- cout << " ceph osd crush move <bucketname> <loc1> [<loc2> ...]\n";
- cout << " ceph osd crush link <bucketname> <loc1> [<loc2> ...]\n";
- cout << " ceph osd crush unlink <bucketname> [ancestor]\n";
- cout << " ceph osd crush add-bucket <bucketname> <type>\n";
- cout << " ceph osd crush reweight <name> <weight>\n";
- cout << " ceph osd crush tunables <legacy|argonaut|bobtail|optimal|default>\n";
- cout << " ceph osd crush rule list\n";
- cout << " ceph osd crush rule dump\n";
- cout << " ceph osd crush rule create-simple <name> <root> <failure-domain>\n";
- cout << " ceph osd create [<uuid>]\n";
- cout << " ceph osd rm <osd-id> [<osd-id>...]\n";
- cout << " ceph osd lost <osd-id> [--yes-i-really-mean-it]\n";
- cout << " ceph osd reweight <osd-id> <weight>\n";
- cout << " ceph osd blacklist add <address>[:source_port] [time]\n";
- cout << " ceph osd blacklist rm <address>[:source_port]\n";
- cout << " ceph osd blacklist ls\n";
- cout << " ceph osd pool mksnap <pool> <snapname>\n";
- cout << " ceph osd pool rmsnap <pool> <snapname>\n";
- cout << " ceph osd pool create <pool> <pg_num> [<pgp_num>]\n";
- cout << " ceph osd pool delete <pool> [<pool> --yes-i-really-really-mean-it]\n";
- cout << " ceph osd pool rename <pool> <new pool name>\n";
- cout << " ceph osd pool set <pool> <field> <value>\n";
- cout << " ceph osd pool set-quota <pool> (max_bytes|max_objects) <value>\n";
- cout << " ceph osd scrub <osd-id>\n";
- cout << " ceph osd deep-scrub <osd-id>\n";
- cout << " ceph osd repair <osd-id>\n";
- cout << " ceph osd tell <osd-id or *> bench [bytes per write] [total bytes]\n";
- cout << "\n";
- cout << "PLACEMENT GROUP (PG) COMMANDS\n";
- cout << " ceph pg dump\n";
- cout << " ceph pg <pg-id> query\n";
- cout << " ceph pg scrub <pg-id>\n";
- cout << " ceph pg deep-scrub <pg-id>\n";
- cout << " ceph pg map <pg-id>\n";
- cout << "\n";
- cout << "OPTIONS\n";
- cout << " -o <file> Write out to <file>\n";
- cout << " -i <file> Read input from <file> (for some commands)\n";
- generic_client_usage(); // Will exit()
-}
-
-static void parse_cmd_args(vector<const char*> &args,
- std::string *in_file, std::string *out_file,
- ceph_tool_mode_t *mode, bool *concise,
- string *admin_socket, string *admin_socket_cmd,
- string *watch_level)
-{
- std::vector<const char*>::iterator i;
- std::string val;
- for (i = args.begin(); i != args.end(); ) {
- if (ceph_argparse_double_dash(args, i)) {
- break;
- } else if (ceph_argparse_witharg(args, i, &val, "-i", "--in-file", (char*)NULL)) {
- *in_file = val;
- } else if (ceph_argparse_witharg(args, i, &val, "-o", "--out-file", (char*)NULL)) {
- *out_file = val;
- } else if (ceph_argparse_witharg(args, i, &val, "--admin-daemon", (char*)NULL)) {
- *admin_socket = val;
- if (i == args.end())
- usage();
- *admin_socket_cmd = *i++;
- } else if (ceph_argparse_flag(args, i, "-s", "--status", (char*)NULL)) {
- *mode = CEPH_TOOL_MODE_STATUS;
- } else if (ceph_argparse_flag(args, i, "-w", "--watch", (char*)NULL)) {
- *mode = CEPH_TOOL_MODE_WATCH;
- } else if (ceph_argparse_flag(args, i, "--watch-debug", (char*) NULL)) {
- *watch_level = "log-debug";
- } else if (ceph_argparse_flag(args, i, "--watch-info", (char*) NULL)) {
- *watch_level = "log-info";
- } else if (ceph_argparse_flag(args, i, "--watch-sec", (char*) NULL)) {
- *watch_level = "log-sec";
- } else if (ceph_argparse_flag(args, i, "--watch-warn", (char*) NULL)) {
- *watch_level = "log-warn";
- } else if (ceph_argparse_flag(args, i, "--watch-error", (char*) NULL)) {
- *watch_level = "log-error";
- } else if (ceph_argparse_flag(args, i, "--concise", (char*)NULL)) {
- *concise = true;
- } else if (ceph_argparse_flag(args, i, "--verbose", (char*)NULL)) {
- *concise = false;
- } else if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
- usage();
- } else {
- if (admin_socket_cmd && admin_socket_cmd->length()) {
- *admin_socket_cmd += " " + string(*i);
- }
- ++i;
- }
- }
-}
-
-static int get_indata(const char *in_file, bufferlist &indata)
-{
- int fd = VOID_TEMP_FAILURE_RETRY(::open(in_file, O_RDONLY));
- if (fd < 0) {
- int err = errno;
- derr << "error opening in_file '" << in_file << "': "
- << cpp_strerror(err) << dendl;
- return 1;
- }
- struct stat st;
- if (::fstat(fd, &st)) {
- int err = errno;
- derr << "error getting size of in_file '" << in_file << "': "
- << cpp_strerror(err) << dendl;
- VOID_TEMP_FAILURE_RETRY(::close(fd));
- return 1;
- }
-
- indata.push_back(buffer::create(st.st_size));
- indata.zero();
- int ret = safe_read_exact(fd, indata.c_str(), st.st_size);
- if (ret) {
- derr << "error reading in_file '" << in_file << "': "
- << cpp_strerror(ret) << dendl;
- VOID_TEMP_FAILURE_RETRY(::close(fd));
- return 1;
- }
-
- VOID_TEMP_FAILURE_RETRY(::close(fd));
- derr << "read " << st.st_size << " bytes from " << in_file << dendl;
- return 0;
-}
-
-int do_admin_socket(string path, string cmd)
-{
- struct sockaddr_un address;
- int fd;
- int r;
-
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if(fd < 0) {
- cerr << "socket failed with " << cpp_strerror(errno) << std::endl;
- return -1;
- }
-
- memset(&address, 0, sizeof(struct sockaddr_un));
- address.sun_family = AF_UNIX;
- snprintf(address.sun_path, UNIX_PATH_MAX, "%s", path.c_str());
-
- if (connect(fd, (struct sockaddr *) &address,
- sizeof(struct sockaddr_un)) != 0) {
- cerr << "connect to " << path << " failed with " << cpp_strerror(errno) << std::endl;
- ::close(fd);
- return -1;
- }
-
- char *buf = NULL;
- uint32_t len;
- r = safe_write(fd, cmd.c_str(), cmd.length() + 1);
- if (r < 0) {
- cerr << "write to " << path << " failed with " << cpp_strerror(errno) << std::endl;
- goto out;
- }
-
- r = safe_read(fd, &len, sizeof(len));
- if (r < 0) {
- cerr << "read " << len << " length from " << path << " failed with " << cpp_strerror(errno) << std::endl;
- goto out;
- }
- if (r < 4) {
- cerr << "read only got " << r << " bytes of 4 expected for response length; invalid command?" << std::endl;
- r = -1;
- goto out;
- }
- len = ntohl(len);
-
- buf = new char[len+1];
- r = safe_read(fd, buf, len);
- if (r < 0) {
- cerr << "read " << len << " bytes from " << path << " failed with " << cpp_strerror(errno) << std::endl;
- goto out;
- }
- buf[len] = '\0';
-
- cout << buf << std::endl;
- r = 0;
-
- out:
- if (buf)
- delete[] buf;
- ::close(fd);
- return r;
-}
-
-
-int main(int argc, const char **argv)
-{
- std::string in_file, out_file;
- enum ceph_tool_mode_t mode = CEPH_TOOL_MODE_CLI_INPUT;
- vector<const char*> args;
- argv_to_vec(argc, argv, args);
- env_to_vec(args);
-
- // initialize globals
- global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
- common_init_finish(g_ceph_context);
-
- // parse user input
- bool concise = true;
- string admin_socket;
- string admin_socket_cmd;
- string watch_level = "log-info";
- parse_cmd_args(args, &in_file, &out_file, &mode, &concise,
- &admin_socket, &admin_socket_cmd, &watch_level);
-
- // daemon admin socket?
- if (admin_socket.length()) {
- return do_admin_socket(admin_socket, admin_socket_cmd);
- }
-
- // input
- bufferlist indata;
- if (!in_file.empty()) {
- if (get_indata(in_file.c_str(), indata)) {
- derr << "failed to get data from '" << in_file << "'" << dendl;
- return 1;
- }
- }
-
- CephToolCtx *ctx = ceph_tool_common_init(mode, concise);
- if (!ctx) {
- derr << "ceph_tool_common_init failed." << dendl;
- return 1;
- }
- signal(SIGINT, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
-
- bufferlist outbl;
- int ret = 0;
- switch (mode) {
- case CEPH_TOOL_MODE_STATUS:
- do_status(ctx, true);
- break;
- case CEPH_TOOL_MODE_WATCH: {
- do_status(ctx);
- ctx->lock.Lock();
- ctx->dispatcher->subs.name = watch_level;
- ctx->dispatcher->subs.last_known_version = 0;
- ctx->mc.sub_want(watch_level, 0, 0);
- ctx->mc.renew_subs();
- ctx->lock.Unlock();
- break;
- }
-
- case CEPH_TOOL_MODE_CLI_INPUT: {
- if (args.empty()) {
- if (ceph_tool_do_cli(ctx))
- ret = 1;
- } else {
- while (!args.empty()) {
- vector<string> cmd;
- for (vector<const char*>::iterator n = args.begin();
- n != args.end(); ) {
- std::string np(*n);
- n = args.erase(n);
- if (np == ";")
- break;
- cmd.push_back(np);
- }
-
- bufferlist obl;
- ret = do_command(ctx, cmd, indata, obl);
- if (ret < 0) {
- ret = -ret;
- break;
- }
- outbl.claim(obl);
- }
- }
- if (ceph_tool_messenger_shutdown())
- ret = 1;
- break;
- }
-
- default: {
- derr << "logic error: illegal ceph command mode " << mode << dendl;
- ret = 1;
- break;
- }
- }
-
- if (ret == 0 && outbl.length()) {
- // output
- int err;
- if (out_file.empty() || out_file == "-") {
- err = outbl.write_fd(STDOUT_FILENO);
- } else {
- int out_fd = VOID_TEMP_FAILURE_RETRY(::open(out_file.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644));
- if (out_fd < 0) {
- int ret = errno;
- derr << " failed to create file '" << out_file << "': "
- << cpp_strerror(ret) << dendl;
- return 1;
- }
- err = outbl.write_fd(out_fd);
- ::close(out_fd);
- }
- if (err) {
- derr << " failed to write " << outbl.length() << " bytes to " << out_file << ": "
- << cpp_strerror(err) << dendl;
- ret = 1;
- } else if (!concise && !out_file.empty())
- cerr << " wrote " << outbl.length() << " byte payload to " << out_file << std::endl;
- }
-
- if (ceph_tool_common_shutdown(ctx))
- ret = 1;
- return ret;
-}
+++ /dev/null
-// -*- 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-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.
- *
- */
-
-#include <sys/stat.h>
-#include <iostream>
-#include <string>
-using namespace std;
-
-#if !defined(DARWIN) && !defined(__FreeBSD__)
-#include <envz.h>
-#endif // DARWIN
-
-#include <memory>
-#include <sys/types.h>
-#include <fcntl.h>
-
-extern "C" {
-#include <histedit.h>
-}
-
-#include "acconfig.h"
-#include "messages/MMonCommand.h"
-#include "messages/MMonCommandAck.h"
-#include "messages/MLog.h"
-#include "mon/MonClient.h"
-#include "mon/MonMap.h"
-#include "osd/OSDMap.h"
-#include "msg/SimpleMessenger.h"
-#include "tools/common.h"
-
-#include "common/errno.h"
-#include "common/Cond.h"
-#include "common/Mutex.h"
-#include "common/Timer.h"
-#include "global/global_init.h"
-
-
-#include "include/assert.h"
-
-#define dout_subsys ceph_subsys_
-
-// TODO: should move these into CephToolCtx for consistency
-static enum ceph_tool_mode_t
- ceph_tool_mode(CEPH_TOOL_MODE_CLI_INPUT);
-static Cond cmd_cond;
-static SimpleMessenger *messenger = 0;
-static Tokenizer *tok;
-
-// sync command
-bool pending_tell; // is tell, vs monitor command
-bool pending_tell_pgid;
-uint64_t pending_tid = 0;
-EntityName pending_target;
-pg_t pending_target_pgid;
-bool cmd_waiting_for_osdmap = false;
-vector<string> pending_cmd;
-bufferlist pending_bl;
-bool reply;
-string reply_rs;
-int reply_rc;
-bufferlist reply_bl;
-entity_inst_t reply_from;
-
-OSDMap *osdmap = 0;
-
-Connection *command_con = NULL;
-Context *tick_event = 0;
-float tick_interval = 3.0;
-
-// observe (push)
-#include "mon/PGMap.h"
-#include "mds/MDSMap.h"
-#include "common/LogEntry.h"
-
-#include "mon/mon_types.h"
-
-#include "messages/MOSDMap.h"
-
-#include "messages/MCommand.h"
-#include "messages/MCommandReply.h"
-
-static set<int> registered, seen;
-
-struct C_Tick : public Context {
- CephToolCtx *ctx;
- C_Tick(CephToolCtx *c) : ctx(c) {}
- void finish(int r) {
- if (command_con)
- messenger->send_keepalive(command_con);
-
- assert(tick_event == this);
- tick_event = new C_Tick(ctx);
- ctx->timer.add_event_after(tick_interval, tick_event);
- }
-};
-
-static void send_command(CephToolCtx *ctx)
-{
- if (!pending_tell && !pending_tell_pgid) {
- version_t last_seen_version = 0;
- MMonCommand *m = new MMonCommand(ctx->mc.monmap.fsid, last_seen_version);
- m->cmd = pending_cmd;
- m->set_data(pending_bl);
-
- if (!ctx->concise)
- *ctx->log << ceph_clock_now(g_ceph_context) << " mon" << " <- " << pending_cmd << std::endl;
-
- ctx->mc.send_mon_message(m);
- return;
- }
-
- if (pending_tell_pgid || pending_target.get_type() == (int)entity_name_t::TYPE_OSD) {
- if (!osdmap) {
- ctx->mc.sub_want("osdmap", 0, CEPH_SUBSCRIBE_ONETIME);
- ctx->mc.renew_subs();
- cmd_waiting_for_osdmap = true;
- return;
- }
- }
-
- if (!ctx->concise)
- *ctx->log << ceph_clock_now(g_ceph_context) << " " << pending_target << " <- " << pending_cmd << std::endl;
-
- if (pending_tell_pgid) {
- // pick target osd
- vector<int> osds;
- int r = osdmap->pg_to_acting_osds(pending_target_pgid, osds);
- if (r < 0) {
- reply_rs = "error mapping pgid to an osd";
- reply_rc = -EINVAL;
- reply = true;
- cmd_cond.Signal();
- return;
- }
- if (r == 0) {
- reply_rs = "pgid currently maps to no osd";
- reply_rc = -ENOENT;
- reply = true;
- cmd_cond.Signal();
- return;
- }
- pending_target.set_name(entity_name_t::OSD(osds[0]));
- }
-
- if (pending_target.get_type() == (int)entity_name_t::TYPE_OSD) {
- const char *start = pending_target.get_id().c_str();
- char *end;
- int n = strtoll(start, &end, 10);
- if (end <= start) {
- stringstream ss;
- ss << "invalid osd id " << pending_target;
- reply_rs = ss.str();
- reply_rc = -EINVAL;
- reply = true;
- cmd_cond.Signal();
- return;
- }
-
- if (!osdmap->is_up(n)) {
- stringstream ss;
- ss << pending_target << " is not up";
- reply_rs = ss.str();
- reply_rc = -ESRCH;
- reply = true;
- cmd_cond.Signal();
- return;
- } else {
- if (!ctx->concise)
- *ctx->log << ceph_clock_now(g_ceph_context) << " " << pending_target << " <- " << pending_cmd << std::endl;
-
- MCommand *m = new MCommand(ctx->mc.monmap.fsid);
- m->cmd = pending_cmd;
- m->set_data(pending_bl);
- m->set_tid(++pending_tid);
-
- command_con = messenger->get_connection(osdmap->get_inst(n));
- messenger->send_message(m, command_con);
-
- if (tick_event)
- ctx->timer.cancel_event(tick_event);
- tick_event = new C_Tick(ctx);
- ctx->timer.add_event_after(tick_interval, tick_event);
- }
- return;
- }
-
- reply_rc = -EINVAL;
- reply = true;
- cmd_cond.Signal();
-}
-
-static void handle_osd_map(CephToolCtx *ctx, MOSDMap *m)
-{
- epoch_t e = m->get_first();
- assert(m->maps.count(e));
- ctx->lock.Lock();
- delete osdmap;
- osdmap = new OSDMap;
- osdmap->decode(m->maps[e]);
- if (cmd_waiting_for_osdmap) {
- cmd_waiting_for_osdmap = false;
- send_command(ctx);
- }
- ctx->lock.Unlock();
- m->put();
-}
-
-static void handle_ack(CephToolCtx *ctx, MMonCommandAck *ack)
-{
- ctx->lock.Lock();
- reply = true;
- reply_from = ack->get_source_inst();
- reply_rs = ack->rs;
- reply_rc = ack->r;
- reply_bl = ack->get_data();
- cmd_cond.Signal();
- ctx->lock.Unlock();
- ack->put();
-}
-
-static void handle_ack(CephToolCtx *ctx, MCommandReply *ack)
-{
- ctx->lock.Lock();
- if (ack->get_tid() == pending_tid) {
- reply = true;
- reply_from = ack->get_source_inst();
- reply_rs = ack->rs;
- reply_rc = ack->r;
- reply_bl = ack->get_data();
- cmd_cond.Signal();
- if (tick_event) {
- ctx->timer.cancel_event(tick_event);
- tick_event = 0;
- }
- }
- ctx->lock.Unlock();
- ack->put();
-}
-
-int do_command(CephToolCtx *ctx,
- vector<string>& cmd, bufferlist& bl, bufferlist& rbl)
-{
- Mutex::Locker l(ctx->lock);
-
- pending_target = EntityName();
- pending_cmd = cmd;
- pending_bl = bl;
- pending_tell = false;
- pending_tell_pgid = false;
- reply = false;
-
- if (!cmd.empty() && cmd[0] == "tell") {
- if (cmd.size() == 1) {
- cerr << "no tell target specified" << std::endl;
- return -EINVAL;
- }
- if (!pending_target.from_str(cmd[1])) {
- cerr << "tell target '" << cmd[1] << "' not a valid entity name" << std::endl;
- return -EINVAL;
- }
- pending_cmd.erase(pending_cmd.begin(), pending_cmd.begin() + 2);
- pending_tell = true;
- }
- if (!cmd.empty() && cmd[0] == "pg") {
- if (cmd.size() == 1) {
- cerr << "pg requires at least one argument" << std::endl;
- return -EINVAL;
- }
- if (pending_target_pgid.parse(cmd[1].c_str())) {
- pending_tell_pgid = true;
- }
- // otherwise, send the request on to the monitor (e.g., 'pg dump'). sigh.
- }
-
- send_command(ctx);
-
- while (!reply)
- cmd_cond.Wait(ctx->lock);
-
- rbl = reply_bl;
- if (!ctx->concise)
- *ctx->log << ceph_clock_now(g_ceph_context) << " "
- << reply_from.name << " -> '"
- << reply_rs << "' (" << reply_rc << ")"
- << std::endl;
- else {
- if (reply_rc >= 0)
- cout << reply_rs << std::endl;
- else
- cerr << reply_rs << std::endl;
- }
-
- return reply_rc;
-}
-
-void do_status(CephToolCtx *ctx, bool shutdown) {
- vector<string> cmd;
- cmd.push_back("status");
- bufferlist bl;
-
- do_command(ctx, cmd, bl, bl);
-
- if (shutdown)
- messenger->shutdown();
-}
-
-static const char *cli_prompt(EditLine *e)
-{
- return "ceph> ";
-}
-
-int ceph_tool_do_cli(CephToolCtx *ctx)
-{
- /* emacs style */
- EditLine *el = el_init("ceph", stdin, stdout, stderr);
- el_set(el, EL_PROMPT, &cli_prompt);
- el_set(el, EL_EDITOR, "emacs");
-
- History *myhistory = history_init();
- if (myhistory == 0) {
- fprintf(stderr, "history could not be initialized\n");
- return 1;
- }
-
- HistEvent ev;
-
- /* Set the size of the history */
- history(myhistory, &ev, H_SETSIZE, 800);
-
- /* This sets up the call back functions for history functionality */
- el_set(el, EL_HIST, history, myhistory);
-
- while (1) {
- int chars_read;
- const char *line = el_gets(el, &chars_read);
-
- //*ctx->log << "typed '" << line << "'" << std::endl;
-
- if (chars_read == 0) {
- *ctx->log << "quit" << std::endl;
- break;
- }
-
- history(myhistory, &ev, H_ENTER, line);
-
- if (run_command(ctx, line))
- break;
- }
-
- history_end(myhistory);
- el_end(el);
-
- return 0;
-}
-
-int run_command(CephToolCtx *ctx, const char *line)
-{
- if (strcmp(line, "quit\n") == 0)
- return 1;
-
- int argc;
- const char **argv;
- tok_str(tok, line, &argc, &argv);
- tok_reset(tok);
-
- vector<string> cmd;
- const char *infile = 0;
- const char *outfile = 0;
- for (int i=0; i<argc; i++) {
- if (strcmp(argv[i], ">") == 0 && i < argc-1) {
- outfile = argv[++i];
- continue;
- }
- if (argv[i][0] == '>') {
- outfile = argv[i] + 1;
- while (*outfile == ' ') outfile++;
- continue;
- }
- if (strcmp(argv[i], "<") == 0 && i < argc-1) {
- infile = argv[++i];
- continue;
- }
- if (argv[i][0] == '<') {
- infile = argv[i] + 1;
- while (*infile == ' ') infile++;
- continue;
- }
- cmd.push_back(argv[i]);
- }
- if (cmd.empty())
- return 0;
-
- bufferlist in;
- if (cmd.size() == 1 && cmd[0] == "print") {
- if (!ctx->concise)
- *ctx->log << "----" << std::endl;
- fwrite(in.c_str(), in.length(), 1, stdout);
- if (!ctx->concise)
- *ctx->log << "---- (" << in.length() << " bytes)" << std::endl;
- return 0;
- }
-
- //out << "cmd is " << cmd << std::endl;
-
- bufferlist out;
- if (infile) {
- std::string error;
- if (out.read_file(infile, &error) == 0) {
- if (!ctx->concise)
- *ctx->log << "read " << out.length() << " from " << infile << std::endl;
- } else {
- *ctx->log << "couldn't read from " << infile << ": "
- << error << std::endl;
- return 0;
- }
- }
-
- in.clear();
- do_command(ctx, cmd, out, in);
-
- if (in.length() == 0)
- return 0;
-
- if (outfile) {
- if (strcmp(outfile, "-") == 0) {
- if (!ctx->concise)
- *ctx->log << "----" << std::endl;
- fwrite(in.c_str(), in.length(), 1, stdout);
- if (!ctx->concise)
- *ctx->log << "---- (" << in.length() << " bytes)" << std::endl;
- }
- else {
- in.write_file(outfile);
- if (!ctx->concise)
- *ctx->log << "wrote " << in.length() << " to "
- << outfile << std::endl;
- }
- }
- else {
- if (!ctx->concise)
- *ctx->log << "got " << in.length() << " byte payload; 'print' "
- << "to dump to terminal, or add '>-' to command." << std::endl;
- }
- return 0;
-}
-
-CephToolCtx* ceph_tool_common_init(ceph_tool_mode_t mode, bool concise)
-{
- ceph_tool_mode = mode;
-
- std::auto_ptr <CephToolCtx> ctx;
- ctx.reset(new CephToolCtx(g_ceph_context, concise));
-
- // get monmap
- if (ctx->mc.build_initial_monmap() < 0)
- return NULL;
-
- // initialize tokenizer
- tok = tok_init(NULL);
-
- // start up network
- messenger = new SimpleMessenger(g_ceph_context, entity_name_t::CLIENT(), "client",
- getpid());
- messenger->set_default_policy(Messenger::Policy::lossy_client(0, 0));
- messenger->start();
-
- ctx->mc.set_messenger(messenger);
-
- ctx->dispatcher = new Admin(ctx.get());
- messenger->add_dispatcher_head(ctx->dispatcher);
-
- int r = ctx->mc.init();
- if (r < 0)
- return NULL;
-
- ctx->lock.Lock();
- ctx->timer.init();
- ctx->lock.Unlock();
-
- // in case we 'tell ...'
- ctx->mc.set_want_keys(CEPH_ENTITY_TYPE_MDS | CEPH_ENTITY_TYPE_OSD);
-
- if (ctx->mc.authenticate() < 0) {
- derr << "unable to authenticate as " << g_conf->name << dendl;
- ceph_tool_messenger_shutdown();
- ceph_tool_common_shutdown(ctx.get());
- return NULL;
- }
- if (ctx->mc.get_monmap() < 0) {
- derr << "unable to get monmap" << dendl;
- ceph_tool_messenger_shutdown();
- ceph_tool_common_shutdown(ctx.get());
- return NULL;
- }
- return ctx.release();
-}
-
-int ceph_tool_messenger_shutdown()
-{
- return messenger->shutdown();
-}
-
-int ceph_tool_common_shutdown(CephToolCtx *ctx)
-{
- // wait for messenger to finish
- messenger->wait();
-
- ctx->lock.Lock();
- ctx->mc.shutdown();
- ctx->timer.shutdown();
- ctx->lock.Unlock();
-
- delete messenger;
- tok_end(tok);
-
- return 0;
-}
-
-void Subscriptions::handle_log(MLog *m)
-{
- dout(10) << __func__ << " received log msg ver " << m->version << dendl;
-
- if (last_known_version >= m->version) {
- dout(10) << __func__
- << " we have already received ver " << m->version
- << " (highest received: " << last_known_version << ") " << dendl;
- return;
- }
- last_known_version = m->version;
-
- std::deque<LogEntry>::iterator it = m->entries.begin();
- for (; it != m->entries.end(); ++it) {
- LogEntry e = *it;
- cout << e.stamp << " " << e.who.name
- << " " << e.type << " " << e.msg << std::endl;
- }
-
- version_t v = last_known_version+1;
- dout(10) << __func__ << " wanting " << name << " ver " << v << dendl;
- ctx->mc.sub_want(name, v, 0);
-}
-
-bool Admin::ms_dispatch(Message *m) {
- switch (m->get_type()) {
- case MSG_MON_COMMAND_ACK:
- handle_ack(ctx, (MMonCommandAck*)m);
- break;
- case MSG_COMMAND_REPLY:
- handle_ack(ctx, (MCommandReply*)m);
- break;
- case CEPH_MSG_MON_MAP:
- m->put();
- break;
- case CEPH_MSG_OSD_MAP:
- handle_osd_map(ctx, (MOSDMap *)m);
- break;
- case MSG_LOG:
- {
- MLog *mlog = (MLog*) m;
- subs.handle_log(mlog);
- break;
- }
- default:
- return false;
- }
- return true;
-}
-
-void Admin::ms_handle_connect(Connection *con) {
- if (con->get_peer_type() == CEPH_ENTITY_TYPE_MON) {
- ctx->lock.Lock();
- if (!pending_cmd.empty())
- send_command(ctx);
- ctx->lock.Unlock();
- }
-}
-
-bool Admin::ms_handle_reset(Connection *con)
-{
- Mutex::Locker l(ctx->lock);
- if (con == command_con) {
- command_con->put();
- command_con = NULL;
- if (!pending_cmd.empty())
- send_command(ctx);
- return true;
- }
- return false;
-}
-
-bool Admin::ms_get_authorizer(int dest_type, AuthAuthorizer **authorizer,
- bool force_new)
-{
- if (dest_type == CEPH_ENTITY_TYPE_MON)
- return true;
- *authorizer = ctx->mc.auth->build_authorizer(dest_type);
- return true;
-}
-
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-#ifndef CEPH_TOOLS_COMMON_DOT_H
-#define CEPH_TOOLS_COMMON_DOT_H
-
-#include <iosfwd>
-#include <stdint.h>
-#include <map>
-
-#include "common/Cond.h"
-#include "common/Mutex.h"
-#include "mon/MonClient.h"
-#include "mon/PGMap.h"
-#include "mds/MDSMap.h"
-#include "osd/OSDMap.h"
-#include "common/Timer.h"
-
-
-#include "common/LogEntry.h"
-#include "mon/mon_types.h"
-#include "messages/MOSDMap.h"
-#include "messages/MLog.h"
-#include "messages/MCommand.h"
-#include "messages/MCommandReply.h"
-#include "messages/MMonCommandAck.h"
-
-
-#define OSD_MON_UPDATE (1<<0)
-#define MDS_MON_UPDATE (1<<1)
-#define PG_MON_UPDATE (1<<2)
-#define MON_MON_UPDATE (1<<3)
-#define EVERYTHING_UPDATE 0xffffffff
-
-class CephContext;
-class CephToolCtx;
-
-enum ceph_tool_mode_t {
- CEPH_TOOL_MODE_CLI_INPUT = 0,
- CEPH_TOOL_MODE_WATCH = 1,
- CEPH_TOOL_MODE_STATUS = 2,
- CEPH_TOOL_MODE_GUI = 3
-};
-
-struct Subscriptions {
- CephToolCtx *ctx;
- version_t last_known_version;
- string name;
-
- Subscriptions(CephToolCtx *c) : ctx(c), last_known_version(0) { }
-
- void handle_log(MLog *m);
-};
-
-class Admin : public Dispatcher {
-private:
- CephToolCtx *ctx;
-public:
- Subscriptions subs;
-
- Admin(CephToolCtx *ctx_)
- : Dispatcher(g_ceph_context),
- ctx(ctx_), subs(ctx_)
- {
- }
-
- bool ms_dispatch(Message *m);
- void ms_handle_connect(Connection *con);
- bool ms_handle_reset(Connection *con);
- void ms_handle_remote_reset(Connection *con) {}
-
- bool ms_get_authorizer(int dest_type, AuthAuthorizer **authorizer, bool force_new);
-};
-
-
-// tool/ceph.cc
-class CephToolCtx
-{
-public:
- CephContext *cct;
- PGMap pgmap;
- MDSMap mdsmap;
- OSDMap osdmap;
- MonClient mc;
-
- // Which aspects of the cluster have been updated recently?
- uint32_t updates;
-
- // The main log for ceph-tool
- std::ostream *log;
-
- // Used by the GUI to read from the log.
- // NULL if there is no GUI active.
- std::ostringstream *slog;
-
- // The ceph-tool lock
- Mutex lock;
- SafeTimer timer;
-
- // A condition variable used to wake up the GUI thread
- Cond gui_cond;
-
- bool concise;
-
- Admin *dispatcher;
-
- CephToolCtx(CephContext *cct_, bool concise_) :
- cct(cct_),
- mc(g_ceph_context),
- updates(EVERYTHING_UPDATE),
- log(&std::cout),
- slog(NULL),
- lock("ceph.cc lock"), timer(cct_, lock),
- concise(concise_),
- dispatcher(NULL)
- {
- }
-
- ~CephToolCtx() {
- delete dispatcher;
- }
-};
-
-// tool/ceph.cc
-int ceph_tool_do_cli(CephToolCtx *data);
-int run_command(CephToolCtx *data, const char *line);
-CephToolCtx* ceph_tool_common_init(ceph_tool_mode_t mode, bool concise);
-int do_command(CephToolCtx *ctx,
- vector<string>& cmd, bufferlist& bl, bufferlist& rbl);
-int ceph_tool_messenger_shutdown();
-int ceph_tool_common_shutdown(CephToolCtx *ctx);
-
-#endif