// -*- 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 * * 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 #include #include using namespace std; #include "config.h" #include "mon/MonMap.h" #include "mon/MonClient.h" #include "msg/SimpleMessenger.h" #include "messages/MMonCommand.h" #include "messages/MMonCommandAck.h" #include "common/Timer.h" #ifndef DARWIN #include #endif // DARWIN #include #include #include Messenger *messenger = 0; const char *outfile = 0; int watch = 0; MonMap monmap; enum { OSD, MON, MDS, CLIENT, LAST }; int which = 0; int same = 0; const char *prefix[4] = { "mds", "osd", "pg", "client" }; string status[4]; void get_next_status() { which++; which = which % LAST; vector vcmd(2); vcmd[0] = prefix[which]; vcmd[1] = "stat"; MMonCommand *m = new MMonCommand(monmap.fsid); m->cmd.swap(vcmd); int mon = monmap.pick_mon(); messenger->send_message(m, monmap.get_inst(mon)); } void handle_ack(MMonCommandAck *ack) { if (watch) { if (ack->rs != status[which]) { status[which] = ack->rs; generic_dout(0) << prefix[which] << " " << status[which] << dendl; same = 0; } else same++; if (same >= LAST) { sleep(1); same = 0; } get_next_status(); } else { generic_dout(0) << ack->get_source() << " -> '" << ack->rs << "' (" << ack->r << ")" << dendl; messenger->shutdown(); } int len = ack->get_data().length(); if (len) { if (outfile) { if (strcmp(outfile, "-") == 0) { ::write(1, ack->get_data().c_str(), len); } else { int fd = ::open(outfile, O_WRONLY|O_TRUNC|O_CREAT); ::write(fd, ack->get_data().c_str(), len); ::fchmod(fd, 0777); ::close(fd); } generic_dout(0) << "wrote " << len << " byte payload to " << outfile << dendl; } else { generic_dout(0) << "got " << len << " byte payload, discarding (specify -o get_type()) { case MSG_MON_COMMAND_ACK: handle_ack((MMonCommandAck*)m); break; } } } dispatcher; void usage() { cerr << "usage: cmonctl [options] monhost] command" << std::endl; cerr << "Options:" << std::endl; cerr << " -m monhost -- specify monitor hostname or ip" << std::endl; cerr << " -i infile -- specify input file" << std::endl; cerr << " -o outfile -- specify output file" << std::endl; cerr << " -w or --watch -- watch mds, osd, pg status" << std::endl; cerr << "Commands:" << std::endl; cerr << " stop -- cleanly shut down file system" << std::endl << " (osd|pg|mds) stat -- get monitor subsystem status" << std::endl << " ..." << std::endl; exit(1); } int main(int argc, const char **argv, const char *envp[]) { vector args; argv_to_vec(argc, argv, args); env_to_vec(args); parse_config_options(args); vec_to_argv(args, argc, argv); bufferlist indata; vector nargs; for (unsigned i=0; i vcmd; string cmd; if (!watch) { for (unsigned i=0; iset_dispatcher(&dispatcher); rank.start(); if (watch) { get_next_status(); } else { // build command MMonCommand *m = new MMonCommand(monmap.fsid); m->set_data(indata); m->cmd.swap(vcmd); int mon = monmap.pick_mon(); generic_dout(0) << "mon" << mon << " <- '" << cmd << "'" << dendl; // send it messenger->send_message(m, monmap.get_inst(mon)); } // wait for messenger to finish rank.wait(); return 0; }