]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
radostool: add simple radostool shell
authorSage Weil <sage@newdream.net>
Sat, 6 Jun 2009 21:38:17 +0000 (14:38 -0700)
committerSage Weil <sage@newdream.net>
Sat, 6 Jun 2009 21:38:17 +0000 (14:38 -0700)
So far just 'lspools' works.

src/Makefile.am
src/TODO
src/include/librados.h
src/librados.cc
src/osd/OSDMap.h
src/radostool.cc [new file with mode: 0644]

index 80c3492dd18db5be9dba02836a8877dffc3389ab..9eb912b73ab446237e7d386b4f603668900a1b5d 100644 (file)
@@ -49,7 +49,7 @@ bin_PROGRAMS = \
        ceph cconf \
        mkmonfs monmaptool osdmaptool crushtool \
        streamtest dupstore dumpjournal testmsgr \
-       testrados testradospp testradoscio
+       testrados testradospp testradoscio radostool
 
 sbin_PROGRAMS = \
        mount.ceph
@@ -112,6 +112,9 @@ librados_la_CXXFLAGS = ${AM_CXXFLAGS}
 librados_la_LDFLAGS = -version-info 1:0:0 -export-symbols-regex 'rados_.*'
 lib_LTLIBRARIES += librados.la
 
+radostool_SOURCES = radostool.cc
+radostool_LDADD = librados.la libcrush.la
+
 testrados_SOURCES = testrados.c
 testrados_LDADD = librados.la libcrush.la
 testradospp_SOURCES = testradospp.cc
index e4fffd32c69c878558b2c020a1a7f6b9ae9c7066..cc52b7431583267dd2683aa0947d742f779a0c5e 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -12,9 +12,15 @@ v0.8
 v0.9
 /- make mds exhert memory pressure on client caps, leases
 /- librados
-  - async io
+/  - async io
   - list_objects
+    - move pg iteration into Objecter (RadosClietn should be a minimal wrapper)
   - perl swig wrapper
+  - radostool
+    - fetch/store/remove object
+    - call method
+    - list objects
+    - list pools
 /- object classes
 - optionally separate osd interfaces (ips) for clients and osds (replication, peering, etc.)
 
index b7a9bb3f9f9e30d73f35880b8f2a182cb911579f..3a4b9384ee6ca6a87e5199e7d67e0450a2f6c81a 100644 (file)
@@ -84,6 +84,7 @@ public:
  };
 
   int list(rados_pool_t pool, int max, std::list<object_t>& entries, Rados::ListCtx& ctx);
+  int list_pools(std::vector<std::string>& v);
 
   // -- aio --
   struct AioCompletion {
index 85ed67d6887a64527b11b52846bbbce6b0dd9ad3..a959d03be1cf38f98eb593813add08d7992ac59d 100644 (file)
@@ -101,6 +101,7 @@ public:
    PGLSOp() : seed(0), cookie(0), pos(0), total(0) {}
   };
 
+  int list_pools(std::vector<string>& ls);
   int list(PoolCtx& pool, int max_entries, std::list<object_t>& entries, RadosClient::PGLSOp& op);
 
   // --- aio ---
@@ -361,6 +362,16 @@ bool RadosClient::_dispatch(Message *m)
   return true;
 }
 
+int RadosClient::list_pools(std::vector<string>& v)
+{
+  Mutex::Locker l(lock);
+  for (map<int,pg_pool_t>::const_iterator p = osdmap.get_pools().begin(); 
+       p != osdmap.get_pools().end();
+       p++)
+    v.push_back(osdmap.get_pool_name(p->first));
+  return 0;
+}
+
 int RadosClient::list(PoolCtx& pool, int max_entries, std::list<object_t>& entries, RadosClient::PGLSOp& op)
 {
   utime_t ut = g_clock.now();
@@ -644,6 +655,13 @@ void Rados::set_snap(rados_pool_t pool, snapid_t seq)
   ctx->set_snap(seq);
 }
 
+int Rados::list_pools(std::vector<string>& v)
+{
+  if (!client)
+    return -EINVAL;
+  return client->list_pools(v);
+}
+
 int Rados::list(rados_pool_t pool, int max, std::list<object_t>& entries, Rados::ListCtx& ctx)
 {
   if (!client)
index e336053fd7fe9662faccb3ee1b7550f7d2299fa4..db5cfae0384349bfe94e77a55c17d28fc1cfacd5 100644 (file)
@@ -779,6 +779,12 @@ private:
     return -1;
   }
 
+  const map<int,pg_pool_t>& get_pools() { return pools; }
+  const char *get_pool_name(int p) {
+    if (pool_name.count(p))
+      return pool_name[p].c_str();
+    return 0;
+  }
   bool have_pg_pool(int p) const {
     return pools.count(p);
   }
diff --git a/src/radostool.cc b/src/radostool.cc
new file mode 100644 (file)
index 0000000..7e80669
--- /dev/null
@@ -0,0 +1,199 @@
+// -*- 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 "include/librados.h"
+#include "config.h"
+#include "common/common_init.h"
+
+#include <iostream>
+
+#include <stdlib.h>
+#include <time.h>
+
+void usage() 
+{
+  cerr << "usage: radostool [options] [commands]" << std::endl;
+  /*  cerr << "If no commands are specified, enter interactive mode.\n";
+  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;
+  */
+  cerr << "Options:" << std::endl;
+  cerr << "   -i infile\n";
+  cerr << "   -o outfile\n";
+  cerr << "        specify input or output file (for certain commands)\n";
+  generic_client_usage();
+}
+
+int main(int argc, const char **argv) 
+{
+  DEFINE_CONF_VARS(usage);
+  vector<const char*> args;
+  argv_to_vec(argc, argv, args);
+  env_to_vec(args);
+  common_init(args, "rados", false);
+
+  vector<const char*> nargs;
+  bufferlist indata;
+  const char *outfile = 0;
+  
+  const char *pool = 0;
+
+  FOR_EACH_ARG(args) {
+    if (CONF_ARG_EQ("out_file", 'o')) {
+      CONF_SAFE_SET_ARG_VAL(&outfile, OPT_STR);
+    } else if (CONF_ARG_EQ("in_data", 'i')) {
+      const char *fname;
+      CONF_SAFE_SET_ARG_VAL(&fname, OPT_STR);
+      int r = indata.read_file(fname);
+      if (r < 0) {
+       cerr << "error reading " << fname << ": " << strerror(-r) << std::endl;
+       exit(0);
+      } else {
+       cout << "read " << indata.length() << " bytes from " << fname << std::endl;
+      }
+    } else if (CONF_ARG_EQ("pool", 'p')) {
+      CONF_SAFE_SET_ARG_VAL(&pool, OPT_STR);
+    } else if (CONF_ARG_EQ("help", 'h')) {
+      usage();
+    } else if (args[i][0] == '-' && nargs.empty()) {
+      cerr << "unrecognized option " << args[i] << std::endl;
+      usage();
+    } else
+      nargs.push_back(args[i]);
+  }
+
+  if (nargs.empty())
+    usage();
+
+  // open rados
+  Rados rados;
+  if (rados.initialize(0, NULL) < 0) {
+     cerr << "couldn't initialize rados!" << std::endl;
+     exit(1);
+  }
+
+  // open pool?
+  rados_pool_t p;
+  if (pool) {
+    int r = rados.open_pool(pool, &p);
+    if (r < 0) {
+      cerr << "error opening pool " << pool << ": " << strerror(-r) << std::endl;
+      exit(0);
+    }
+  }
+
+  // list pools?
+  if (strcmp(nargs[0], "lspools") == 0) {
+    vector<string> vec;
+    rados.list_pools(vec);
+    for (vector<string>::iterator i = vec.begin(); i != vec.end(); ++i)
+      cout << *i << std::endl;
+
+  } else if (strcmp(nargs[0], "ls") == 0) {
+    if (!pool)
+      usage();
+
+    Rados::ListCtx ctx;
+    while (1) {
+      list<object_t> vec;
+      int r = rados.list(p, 2, vec, ctx);
+      cout << "list result=" << r << " entries=" << vec.size() << std::endl;
+      if (r < 0) {
+       cerr << "got error: " << strerror(-r) << std::endl;
+       break;
+      }
+      if (vec.empty())
+       break;
+      for (list<object_t>::iterator iter = vec.begin(); iter != vec.end(); ++iter)
+       cout << *iter << std::endl;
+    }
+
+  } else {
+    cerr << "unrecognized command " << nargs[0] << std::endl;
+    usage();
+  }
+
+  if (pool)
+    rados.close_pool(p);
+
+  rados_deinitialize();
+  return 0;
+}
+/*
+    // pool
+    const char *cmd = nargs[0];
+  
+
+  if (!pool)
+    usage();
+
+
+  // init rados
+  Rados rados;
+  if (rados.initialize(0, NULL) < 0) {
+     cerr << "couldn't initialize rados!" << std::endl;
+     exit(1);
+  }
+
+  rados_pool_t pool;
+  int r = rados.open_pool("data", &pool);
+  cout << "open pool result = " << r << " pool = " << pool << std::endl;
+
+  rados.write(pool, oid, 0, bl, bl.length());
+  rados.write(pool, oid, 0, bl, bl.length() - 1);
+  rados.write(pool, oid, 0, bl, bl.length() - 2);
+  rados.write(pool, oid, 0, bl, bl.length() - 3);
+  rados.write(pool, oid, 0, bl, bl.length() - 4);
+  r = rados.exec(pool, oid, "crypto", "md5", bl, bl2);
+  cout << "exec returned " << r << std::endl;
+  const unsigned char *md5 = (const unsigned char *)bl2.c_str();
+  char md5_str[bl2.length()*2 + 1];
+  buf_to_hex(md5, bl2.length(), md5_str);
+  cout << "md5 result=" << md5_str << std::endl;
+
+  r = rados.exec(pool, oid, "crypto", "sha1", bl, bl2);
+  cout << "exec returned " << r << std::endl;
+  const unsigned char *sha1 = (const unsigned char *)bl2.c_str();
+  char sha1_str[bl2.length()*2 + 1];
+  buf_to_hex(sha1, bl2.length(), sha1_str);
+  cout << "sha1 result=" << sha1_str << std::endl;
+
+  int size = rados.read(pool, oid, 0, bl2, 128);
+  cout << "read result=" << bl2.c_str() << std::endl;
+  cout << "size=" << size << std::endl;
+
+  Rados::ListCtx ctx;
+  int entries;
+  do {
+    list<object_t> vec;
+    r = rados.list(pool, 2, vec, ctx);
+    entries = vec.size();
+    cout << "list result=" << r << " entries=" << entries << std::endl;
+    list<object_t>::iterator iter;
+    for (iter = vec.begin(); iter != vec.end(); ++iter) {
+      cout << *iter << std::endl;
+    }
+  } while (entries);
+#if 0
+  r = rados.remove(pool, oid);
+  cout << "remove result=" << r << std::endl;
+  rados.close_pool(pool);
+#endif
+
+  return 0;
+}
+
+*/