]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: implement some more functionality
authorYehuda Sadeh <yehuda.sadeh@dreamhost.com>
Thu, 27 Jan 2011 00:17:55 +0000 (16:17 -0800)
committerYehuda Sadeh <yehuda.sadeh@dreamhost.com>
Mon, 7 Feb 2011 22:41:57 +0000 (14:41 -0800)
src/include/librbd.hpp
src/librbd.cc
src/rbd.cc

index 20b7a5422126d2b703782b5f9729b968da5d6f72..9ca79aab76a2479525df77b89245aa55ed0fc8ab 100644 (file)
@@ -69,11 +69,16 @@ public:
   int resize(pool_t pool, const char *name, size_t size);
   int stat(pool_t pool, const char *name, image_info_t& info);
   int list(pool_t pool, std::vector<string>& names);
+  int copy(pool_t src_pool, const char *imgname, pool_t dest_pool, const char *destname);
+  int rename(pool_t src_pool, const char *imgname, const char *destname);
 
-  int create_snap(pool_t pool, const char *image_name, const char *snapname);
-  int remove_snap(pool_t pool, const char *image_name, const char *snapname);
-  int rollback_snap(pool_t pool, const char *image_name, const char *snapname);
+  int create_snap(pool_t pool, const char *image_name, const char *snap_name);
+  int remove_snap(pool_t pool, const char *image_name, const char *snap_name);
+  int rollback_snap(pool_t pool, const char *image_name, const char *snap_name);
   int list_snaps(pool_t pool, const char *image_name, std::vector<snap_info_t>& snaps);
+  int set_snap(pool_t pool, const char *image_name, const char *snap_name);
+
+  void get_rados_pools(pool_t pool, librados::pool_t *md_pool, librados::pool_t *data_pool);
 };
 
 }
index cdbb7c747ec25da3499fe7a856c0e09ddc5a73e3..d256c86c3d825ee76b349073fb4d6525396f6a0f 100644 (file)
 
 namespace librbd {
 
-  typedef uint64_t snap_t;
-
   using ceph::bufferlist;
-
-  struct SnapContext {
-    snap_t seq;
-    std::vector<snap_t> snaps;
-  };
+  using librados::snap_t;
 
   struct PoolCtx {
     pool_t md;
@@ -64,10 +58,11 @@ public:
   int initialize(int argc, const char *argv[]);
   void shutdown();
 
+  int set_snap(PoolCtx *pp, const char *image_name, const char *snap_name);
   int list(PoolCtx *pp, std::vector<string>& names);
   int create_snap(PoolCtx *pp, const char *image_name, const char *snap_name);
   int create(pool_t& pool, string& md_oid, const char *imgname, uint64_t size, int *order);
-  int rename(PoolCtx *pp, string& md_oid, const char *imgname, const char *dstname);
+  int rename(PoolCtx *pp, const char *imgname, const char *dstname);
   int info(PoolCtx *pp, string& md_oid, image_info_t& info);
   int remove(PoolCtx *pp, string& md_oid, const char *imgname);
   int resize(PoolCtx *pp, string& md_oid, const char *imgname, uint64_t size);
@@ -78,7 +73,7 @@ public:
                   ::SnapContext& snapc, vector<snap_t>& snaps, uint64_t& snapid);
   int rollback_snap(PoolCtx *pp, const char *image_name, const char *snap_name);
   int remove_snap(PoolCtx *pp, const char *image_name, const char *snap_name);
-  int copy(PoolCtx *pp, const char *imgname, const char *destname);
+  int copy(PoolCtx *pp, const char *imgname, PoolCtx *pp_dest, const char *destname);
 
   int open_pools(const char *poolname, PoolCtx *pp);
   void close_pools(PoolCtx *pp);
@@ -447,8 +442,10 @@ int librbd::RBDClient::create(pool_t& pool, string& md_oid, const char *imgname,
   return 0;
 }
 
-int librbd::RBDClient::rename(PoolCtx *pp, string& md_oid, const char *imgname, const char *dstname)
+int librbd::RBDClient::rename(PoolCtx *pp, const char *imgname, const char *dstname)
 {
+  string md_oid = imgname;
+  md_oid += RBD_SUFFIX;
   string dst_md_oid = dstname;
   dst_md_oid += RBD_SUFFIX;
   string dstname_str = dstname;
@@ -706,13 +703,12 @@ int librbd::RBDClient::rollback_snap(PoolCtx *pp, const char *image_name, const
   return 0;
 }
 
-int librbd::RBDClient::copy(PoolCtx *pp, const char *imgname, const char *destname)
+int librbd::RBDClient::copy(PoolCtx *pp, const char *imgname, PoolCtx *pp_dest, const char *destname)
 {
   struct rbd_obj_header_ondisk header, dest_header;
   int64_t ret;
   int r;
   string md_oid, dest_md_oid;
-  pool_t dest_pool;
 
   md_oid = imgname;
   md_oid += RBD_SUFFIX;
@@ -728,13 +724,13 @@ int librbd::RBDClient::copy(PoolCtx *pp, const char *imgname, const char *destna
   uint64_t block_size = get_block_size(&header);
   int order = header.options.order;
 
-  r = create(dest_pool, dest_md_oid, destname, header.image_size, &order);
+  r = create(pp_dest->md, dest_md_oid, destname, header.image_size, &order);
   if (r < 0) {
     cerr << "header creation failed" << std::endl;
     return r;
   }
 
-  ret = read_header(dest_pool, dest_md_oid, &dest_header, NULL);
+  ret = read_header(pp_dest->md, dest_md_oid, &dest_header, NULL);
   if (ret < 0) {
     cerr << "failed to read newly created header" << std::endl;
     return ret;
@@ -762,7 +758,7 @@ int librbd::RBDClient::copy(PoolCtx *pp, const char *imgname, const char *destna
        return -EIO;
       }
       bl.copy(extent_ofs, extent_len, wrbl);
-      r = rados.write(dest_pool, dest_oid, extent_ofs, wrbl, extent_len);
+      r = rados.write(pp_dest->data, dest_oid, extent_ofs, wrbl, extent_len);
       if (r < 0)
        goto done;
     }
@@ -804,6 +800,27 @@ void librbd::RBDClient::shutdown()
   rados.shutdown();
 }
 
+int librbd::RBDClient::set_snap(PoolCtx *pp, const char *image_name, const char *snap_name)
+{
+  SnapContext snapc;
+  uint64_t snapid;
+  string md_oid = image_name;
+  vector<snap_t> snaps;
+  md_oid += RBD_SUFFIX;
+
+  int r = get_snapc(pp, md_oid, snap_name, snapc, snaps, snapid);
+  if (r < 0)
+    return r;
+
+  r = rados.set_snap_context(pp->data, snapc.seq, snaps);
+  if (r < 0)
+    return r;
+
+  rados.set_snap(pp->data, snapid);
+
+  return 0;
+}
+
 void librbd::RBD::version(int *major, int *minor, int *extra)
 {
   librbd_version(major, minor, extra);
@@ -910,6 +927,21 @@ int librbd::RBD::list(pool_t pool, std::vector<string>& names)
   return r;
 }
 
+int librbd::RBD::copy(pool_t src_pool, const char *imgname, pool_t dest_pool, const char *destname)
+{
+  PoolCtx *src_ctx = (PoolCtx *)src_pool;
+  PoolCtx *dest_ctx = (PoolCtx *)dest_pool;
+  int r = ((librbd::RBDClient *)client)->copy(src_ctx, imgname, dest_ctx, destname);
+  return r;
+}
+
+int librbd::RBD::rename(pool_t src_pool, const char *imgname, const char *destname)
+{
+  PoolCtx *ctx = (PoolCtx *)src_pool;
+  int r = ((librbd::RBDClient *)client)->rename(ctx, imgname, destname);
+  return r;
+}
+
 int librbd::RBD::create_snap(pool_t pool, const char *image_name, const char *snap_name)
 {
   PoolCtx *ctx = (PoolCtx *)pool;
@@ -940,6 +972,21 @@ int librbd::RBD::list_snaps(pool_t pool, const char* image_name, std::vector<lib
   return r;
 }
 
+int librbd::RBD::set_snap(pool_t pool, const char *image_name, const char *snap_name)
+{
+  PoolCtx *ctx = (PoolCtx *)pool;
+  return ((librbd::RBDClient *)client)->set_snap(ctx, image_name, snap_name);
+}
+
+void librbd::RBD::get_rados_pools(pool_t pool, librados::pool_t *md_pool, librados::pool_t *data_pool)
+{
+  PoolCtx *ctx = (PoolCtx *)pool;
+  if (md_pool)
+    *md_pool = ctx->md;
+  if (data_pool)
+    *data_pool = ctx->data;
+}
+
 }
 
 extern "C" void librbd_version(int *major, int *minor, int *extra)
index de4671cdb4248daefd9151f75bdf3a574d23a565..3c4b4d023d2ba7cd585d81dd3fdbe22a5a21340b 100644 (file)
@@ -336,45 +336,14 @@ static int do_create(librbd::pool_t pool, const char *imgname, size_t size)
     return r;
   return 0;
 }
-/*
-static int do_rename(const char *poolname, const char *imgname, const char *destname)
-{
-  string dst_md_oid = dstname;
-  dst_md_oid += RBD_SUFFIX;
-  string dstname_str = dstname;
-  string imgname_str = imgname;
-  uint64_t ver;
-  bufferlist header;
-  int r = read_header_bl(pp.md, md_oid, header, &ver);
-  if (r < 0) {
-    cerr << "error reading header: " << md_oid << ": " << strerror(-r) << std::endl;
-    return r;
-  }
-  r = rados.stat(pp.md, dst_md_oid, NULL, NULL);
-  if (r == 0) {
-    cerr << "rbd image header " << dst_md_oid << " already exists" << std::endl;
-    return -EEXIST;
-  }
-  r = write_header(pp, dst_md_oid, header);
-   if (r < 0) {
-    cerr << "error writing header: " << dst_md_oid << ": " << strerror(-r) << std::endl;
-     return r;
-  }
-  r = tmap_set(pp, dstname_str);
-  if (r < 0) {
-    rados.remove(pp.md, dst_md_oid);
-    cerr << "can't add " << dst_md_oid << " to directory" << std::endl;
-    return r;
-  }
-  r = tmap_rm(pp, imgname_str);
-  if (r < 0)
-    cerr << "warning: couldn't remove old entry from directory (" << imgname_str << ")" << std::endl;
 
-  r = rados.remove(pp.md, md_oid);
+static int do_rename(librbd::pool_t pool, const char *imgname, const char *destname)
+{
+  int r = rbd.rename(pool, imgname, destname);
   if (r < 0)
-    cerr << "warning: couldn't remove old metadata" << std::endl;
+    return r;
+  return 0;
 }
-*/
 
 static int do_show_info(librbd::pool_t pool, const char *imgname)
 {
@@ -444,14 +413,16 @@ static int do_rollback_snap(librbd::pool_t pool, const char *imgname, const char
 
   return 0;
 }
-/*
-static int do_export(librbd::pools_t& pp, string& md_oid, const char *path)
+#if 0
+static int do_export(librbd::pool_t pool, string& md_oid, const char *path)
 {
   struct rbd_obj_header_ondisk header;
   int64_t ret;
   int r;
 
-  ret = read_header(pp.md, md_oid, &header, NULL);
+  librados::pool_t pool_md, pool_data;
+
+  ret = read_header(pool_md, md_oid, &header, NULL);
   if (ret < 0)
     return ret;
 
@@ -469,7 +440,7 @@ static int do_export(librbd::pools_t& pp, string& md_oid, const char *path)
     map<off_t, size_t> m;
     map<off_t, size_t>::iterator iter;
     off_t bl_ofs = 0;
-    r = rados.sparse_read(pp.data, oid, 0, block_size, m, bl);
+    r = rados.sparse_read(pool_data, oid, 0, block_size, m, bl);
     if (r < 0 && r == -ENOENT)
       r = 0;
     if (r < 0) {
@@ -508,7 +479,7 @@ done:
   close(fd);
   return ret;
 }
-*/
+#endif
 static const char *imgname_from_path(const char *path)
 {
   const char *imgname;
@@ -706,71 +677,14 @@ done:
 
   return r;
 }
+#endif
 
-static int do_copy(librbd::pools_t& pp, const char *imgname, const char *destname)
+static int do_copy(librbd::pool_t& pp, const char *imgname, librbd::pool_t& dest_pp, const char *destname)
 {
-  struct rbd_obj_header_ondisk header, dest_header;
-  int64_t ret;
-  int r;
-  string md_oid, dest_md_oid;
-
-  md_oid = imgname;
-  md_oid += RBD_SUFFIX;
-
-  dest_md_oid = destname;
-  dest_md_oid += RBD_SUFFIX;
-
-  ret = read_header(pp.md, md_oid, &header, NULL);
-  if (ret < 0)
-    return ret;
-
-  uint64_t numseg = get_max_block(&header);
-  uint64_t block_size = get_block_size(&header);
-  int order = header.options.order;
-
-  r = do_create(pp.dest, dest_md_oid, destname, header.image_size, &order);
-  if (r < 0) {
-    cerr << "header creation failed" << std::endl;
+  int r = rbd.copy(pp, imgname, dest_pp, destname);
+  if (r < 0)
     return r;
-  }
-
-  ret = read_header(pp.dest, dest_md_oid, &dest_header, NULL);
-  if (ret < 0) {
-    cerr << "failed to read newly created header" << std::endl;
-    return ret;
-  }
-
-  for (uint64_t i = 0; i < numseg; i++) {
-    bufferlist bl;
-    string oid = get_block_oid(&header, i);
-    string dest_oid = get_block_oid(&dest_header, i);
-    map<off_t, size_t> m;
-    map<off_t, size_t>::iterator iter;
-    r = rados.sparse_read(pp.data, oid, 0, block_size, m, bl);
-    if (r < 0 && r == -ENOENT)
-      r = 0;
-    if (r < 0)
-      return r;
-
-
-    for (iter = m.begin(); iter != m.end(); ++iter) {
-      off_t extent_ofs = iter->first;
-      size_t extent_len = iter->second;
-      bufferlist wrbl;
-      if (extent_ofs + extent_len > bl.length()) {
-        cerr << "data error!" << std::endl;
-        return -EIO;
-      }
-      bl.copy(extent_ofs, extent_len, wrbl);
-      r = rados.write(pp.dest, dest_oid, extent_ofs, wrbl, extent_len);
-      if (r < 0)
-        goto done;
-    }
-  }
-  r = 0;
-
-done:
-  return r;
+  return 0;
 }
 
 class RbdWatchCtx : public librados::Rados::WatchCtx {
@@ -783,17 +697,20 @@ public:
   }
 };
 
-static int do_watch(librbd::pools_t& pp, const char *imgname)
+static int do_watch(librbd::pool_t& pp, const char *imgname)
 {
   string md_oid, dest_md_oid;
   uint64_t cookie;
   RbdWatchCtx ctx(imgname);
+  librados::pool_t md_pool;
+
+  rbd.get_rados_pools(pp, &md_pool, NULL);
 
   md_oid = imgname;
   md_oid += RBD_SUFFIX;
 
   librados::Rados rados;
-  int r = rados.watch(pp.md, md_oid, 0, &cookie, &ctx);
+  int r = rados.watch(md_pool, md_oid, 0, &cookie, &ctx);
   if (r < 0) {
     cerr << "watch failed" << std::endl;
     return r;
@@ -803,7 +720,7 @@ static int do_watch(librbd::pools_t& pp, const char *imgname)
   getchar();
   return 0;
 }
-#endif
+
 static void err_exit(librbd::pool_t pool)
 {
   rbd.close_pool(pool);
@@ -1000,6 +917,8 @@ int main(int argc, const char **argv)
   if (!dest_poolname)
     dest_poolname = poolname;
 
+  librbd::pool_t dest_pool;
+
   if (opt_cmd == OPT_EXPORT && !path)
     path = imgname;
 
@@ -1019,38 +938,22 @@ int main(int argc, const char **argv)
       err_exit(pool);
   }
 
-  /*
   if (snapname) {
-    r = do_get_snapc(pp, md_oid, snapname, snapc, snaps, snapid);
-    if (r == -ENOENT) {
-      if (opt_cmd == OPT_SNAP_CREATE)
-        r = 0;
-      else
-        cerr << "snapshot not found: " << snapname << std::endl;
-    }
-    if (r < 0) {
-      cerr << "error searching for snapshot: " << strerror(-r) << std::endl;
-      err_exit(pp);
-    }
-
-    r = rados.set_snap_context(pool, snapc.seq, snaps);
-    if (r < 0) {
+    r = rbd.set_snap(pool, imgname, snapname);
+    if (r < 0 && !(r == -ENOENT && opt_cmd == OPT_SNAP_CREATE)) {
       cerr << "error setting snapshot context: " << strerror(-r) << std::endl;
-      err_exit(pp);
+      err_exit(pool);
     }
-
-    rados.set_snap(pool, snapid);
   }
 
   if (opt_cmd == OPT_COPY || opt_cmd == OPT_IMPORT) {
-    r = rados.open_pool(dest_poolname, &dest_pool);
+    r = rbd.open_pool(dest_poolname, &dest_pool);
     if (r < 0) {
       cerr << "error opening pool " << dest_poolname << " (err=" << r << ")" << std::endl;
-      err_exit(pp);
+      err_exit(pool);
     }
-    pp.dest = dest_pool;
   }
-  */
+
   switch (opt_cmd) {
   case OPT_LIST:
     r = do_list(poolname);
@@ -1083,15 +986,15 @@ int main(int argc, const char **argv)
       err_exit(pool);
     }
     break;
-/*
+
   case OPT_RENAME:
-    r = do_rename(poolname, imgname, destname);
+    r = do_rename(pool, imgname, destname);
     if (r < 0) {
       cerr << "rename error: " << strerror(-r) << std::endl;
       err_exit(pool);
     }
     break;
-*/
+
   case OPT_INFO:
     r = do_show_info(pool, imgname);
     if (r < 0) {
@@ -1163,47 +1066,46 @@ int main(int argc, const char **argv)
       err_exit(pool);
     }
     break;
-    /*
+#if 0
   case OPT_EXPORT:
     if (!path) {
       cerr << "pathname should be specified" << std::endl;
-      err_exit(pp);
+      err_exit(pool);
     }
-    r = do_export(pp, md_oid, path);
+    r = do_export(pool, md_oid, path);
     if (r < 0) {
       cerr << "export error: " << strerror(-r) << std::endl;
-      err_exit(pp);
+      err_exit(pool);
     }
     break;
 
   case OPT_IMPORT:
      if (!path) {
       cerr << "pathname should be specified" << std::endl;
-      err_exit(pp);
+      err_exit(pool);
     }
-    r = do_import(pp.dest, destname, order, path);
+    r = do_import(dest_pool, destname, order, path);
     if (r < 0) {
       cerr << "import failed: " << strerror(-r) << std::endl;
-      err_exit(pp);
+      err_exit(pool);
     }
     break;
-
+#endif
   case OPT_COPY:
-    r = do_copy(pp, imgname, destname);
+    r = do_copy(pool, imgname, dest_pool, destname);
     if (r < 0) {
       cerr << "copy failed: " << strerror(-r) << std::endl;
-      err_exit(pp);
+      err_exit(pool);
     }
     break;
 
   case OPT_WATCH:
-    r = do_watch(pp, imgname);
+    r = do_watch(pool, imgname);
     if (r < 0) {
       cerr << "watch failed: " << strerror(-r) << std::endl;
-      err_exit(pp);
+      err_exit(pool);
     }
     break;
-    */
   }
 
   rbd.close_pool(pool);