]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
fsconverter.cc: Added fsconverter
authorSamuel Just <rexludorum@gmail.com>
Thu, 25 Aug 2011 15:39:37 +0000 (08:39 -0700)
committerSamuel Just <samuel.just@dreamhost.com>
Tue, 30 Aug 2011 00:43:06 +0000 (17:43 -0700)
fsconverter updates an existing FileStore to the most recent FileStore
format

Signed-off-by: Samuel Just <rexludorum@gmail.com>
src/.gitignore
src/Makefile.am
src/fsconverter.cc [new file with mode: 0644]

index 8436e80af84e2ed6d5316c7c57050e7e483872aa..f31a54833eba1136a3aac5cdf161e73981959139 100644 (file)
@@ -46,6 +46,7 @@
 /test_store
 /test_libcommon_build
 /test_mutate
+/fsconverter
 dev
 mondata
 log
index fec53138dfab57512caaca00d6040ccfbd35fd60..f9561e77100f536b9ad060da7a2d3bae4dc9f8f8 100644 (file)
@@ -97,6 +97,10 @@ osdmaptool_SOURCES = osdmaptool.cc
 osdmaptool_LDADD = $(LIBGLOBAL_LDA)
 bin_PROGRAMS += monmaptool crushtool osdmaptool
 
+fsconverter_SOURCES = fsconverter.cc
+fsconverter_LDADD = libos.la $(LIBGLOBAL_LDA)
+bin_PROGRAMS += fsconverter
+
 mount_ceph_SOURCES = mount/mount.ceph.c common/armor.c common/safe_io.c common/secret.c include/addr_parsing.c
 mount_ceph_LDADD = -lkeyutils
 sbin_PROGRAMS += mount.ceph
@@ -114,7 +118,7 @@ csyn_SOURCES = csyn.cc client/SyntheticClient.cc
 csyn_LDADD = libclient.la libosdc.la $(LIBGLOBAL_LDA)
 bin_PROGRAMS += csyn
 
-core: cmon cosd cmds ceph cephfs librados-config cconf monmaptool osdmaptool crushtool csyn
+core: cmon cosd cmds ceph cephfs librados-config cconf monmaptool osdmaptool crushtool csyn fsconverter
 
 
 # fuse targets?
@@ -1352,7 +1356,7 @@ noinst_HEADERS = \
        test/rados-api/test.h
 
 all_sources = $(cmon_SOURCES) $(ceph_SOURCES) $(cephfs_SOURCES) $(librados_config_SOURCES) $(cauthtool_SOURCES) $(monmaptool_SOURCES) \
-       $(crushtool_SOURCES) $(osdmaptool_SOURCES) $(cconf_SOURCES) $(mount_ceph_SOURCES) $(cmds_SOURCES) \
+       $(fsconverter_SOURCES) $(crushtool_SOURCES) $(osdmaptool_SOURCES) $(cconf_SOURCES) $(mount_ceph_SOURCES) $(cmds_SOURCES) \
        $(cosd_SOURCES) $(dupstore_SOURCES) $(store_test_SOURCES) $(streamtest_SOURCES) $(csyn_SOURCES)  \
        $(testmsgr_SOURCES) $(cfuse_SOURCES) $(fakefuse_SOURCES) $(psim_SOURCES) \
        $(libcommon_files) $(libmon_la_SOURCES) $(libmds_a_SOURCES) \
diff --git a/src/fsconverter.cc b/src/fsconverter.cc
new file mode 100644 (file)
index 0000000..7d4c571
--- /dev/null
@@ -0,0 +1,135 @@
+// -*- 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 <iostream>
+#include "os/FileStore.h"
+#include "common/ceph_argparse.h"
+#include "global/global_init.h"
+#include <boost/scoped_ptr.hpp>
+
+#include <ext/hash_map>
+using __gnu_cxx::hash_map;
+
+void usage() {
+  cerr << "usage: fsconverter filestore_path journal_path" << std::endl;
+  exit(0);
+}
+
+int convert_collection(ObjectStore *store, coll_t cid) {
+  vector<hobject_t> objects;
+  int r = store->collection_list(cid, objects);
+  if (r < 0)
+    return r;
+  string temp_name("temp");
+  map<string, bufferptr> aset;
+  r = store->collection_getattrs(cid, aset);
+  if (r < 0)
+    return r;
+  while (store->collection_exists(coll_t(temp_name)))
+    temp_name = "_" + temp_name;
+  coll_t temp(temp_name);
+  
+  ObjectStore::Transaction t;
+  t.collection_rename(cid, temp);
+  t.create_collection(cid);
+  for (vector<hobject_t>::iterator obj = objects.begin();
+       obj != objects.end();
+       ++obj) {
+    t.collection_add(cid, temp, *obj);
+    t.collection_remove(temp, *obj);
+  }
+  for (map<string,bufferptr>::iterator i = aset.begin();
+       i != aset.end();
+       ++i) {
+    bufferlist bl;
+    bl.append(i->second);
+    t.collection_setattr(cid, i->first, bl);
+  }
+  t.remove_collection(temp);
+  r = store->apply_transaction(t);
+  if (r < 0)
+    return r;
+  store->sync_and_flush();
+  store->sync();
+  return 0;
+}
+
+int main(int argc, const char **argv) {
+  vector<const char*> args;
+  argv_to_vec(argc, argv, args);
+  env_to_vec(args);
+
+  global_init(args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
+  common_init_finish(g_ceph_context);
+
+  // args
+  if (args.size() != 2) 
+    usage();
+
+  boost::scoped_ptr<ObjectStore> store(new FileStore(args[0], args[1]));
+  g_ceph_context->_conf->filestore_update_collections = true;;
+  g_ceph_context->_conf->debug_filestore = 20;
+  int r = store->mount();
+  if (r < 0)
+    return -r;
+
+  uint32_t version;
+  r = store->version_stamp_is_valid(&version);
+  if (r < 0)
+    return -r;
+  if (r == -1) {
+    cerr << "FileStore is up to date." << std::endl;
+    store->umount();
+    return 0;
+  } else {
+    cerr << "FileStore is old at version " << version << ".  Updating..." 
+        << std::endl;
+  }
+
+  cerr << "Getting collections" << std::endl;
+  vector<coll_t> collections;
+  r = store->list_collections(collections);
+  if (r < 0)
+    return -r;
+
+  cerr << collections.size() << " to process." << std::endl;
+  int processed = 0;
+  for (vector<coll_t>::iterator i = collections.begin();
+       i != collections.end();
+       ++i, ++processed) {
+    cerr << processed << "/" << collections.size() << " processed" << std::endl;
+    uint32_t collection_version;
+    r = store->collection_version_current(*i, &collection_version);
+    if (r < 0) {
+      return r;
+    } else if (r == 1) {
+      cerr << "Collection " << *i << " is up to date" << std::endl;
+    } else {
+      cerr << "Updating collection " << *i << " current version is " << collection_version << std::endl;
+      r = convert_collection(store.get(), *i);
+      if (r < 0)
+       return r;
+      cerr << "collection " << *i << " updated" << std::endl;
+    }
+  }
+  cerr << "All collections up to date, updating version stamp..." << std::endl;
+  r = store->update_version_stamp();
+  if (r < 0)
+    return r;
+  store->sync_and_flush();
+  store->sync();
+  cerr << "Version stamp updated, done!" << std::endl;
+  store->umount();
+  return 0;
+}