From 1b363dde22a4f421c7be14347b7591f814a35950 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 2 Jul 2010 15:27:44 -0700 Subject: [PATCH] rbdtool: implement import still doesn't use fiemap --- src/rbdtool.cc | 122 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 106 insertions(+), 16 deletions(-) diff --git a/src/rbdtool.cc b/src/rbdtool.cc index e0312922ab90e..eb82df42da11b 100644 --- a/src/rbdtool.cc +++ b/src/rbdtool.cc @@ -52,8 +52,10 @@ void usage() << "\t rollback image head to specified snapshot\n" << "\t--rename \n" << "\t rename rbd image\n" - << "\t--export \n" - << "\t export image to path\n"; + << "\t--export \n" + << "\t export image to file\n" + << "\t--import \n" + << "\t import image from file\n"; } void usage_exit() @@ -64,7 +66,7 @@ void usage_exit() static void init_rbd_header(struct rbd_obj_header_ondisk& ondisk, - size_t size, int order, uint64_t bid) + size_t size, int *order, uint64_t bid) { uint32_t hi = bid >> 32; uint32_t lo = bid & 0xFFFFFFFF; @@ -76,11 +78,11 @@ static void init_rbd_header(struct rbd_obj_header_ondisk& ondisk, snprintf(ondisk.block_name, sizeof(ondisk.block_name), "rb.%x.%x", hi, lo); + if (!*order) + *order = RBD_DEFAULT_OBJ_ORDER; + ondisk.image_size = size; - if (order) - ondisk.options.order = order; - else - ondisk.options.order = RBD_DEFAULT_OBJ_ORDER; + ondisk.options.order = *order; ondisk.options.crypt_type = RBD_CRYPT_NONE; ondisk.options.comp_type = RBD_COMP_NONE; ondisk.snap_seq = 0; @@ -111,7 +113,8 @@ static uint64_t get_max_block(rbd_obj_header_ondisk *header) { uint64_t size = header->image_size; int obj_order = header->options.order; - uint64_t numseg = size >> obj_order; + uint64_t block_size = 1 << obj_order; + uint64_t numseg = (size + block_size - 1) >> obj_order; return numseg; } @@ -288,7 +291,7 @@ static int do_list(pool_t pool, const char *poolname, string& dir_oid) } static int do_create(pool_t pool, string& dir_oid, string& dir_info_oid, string& md_oid, - const char *imgname, uint64_t size, int order) + const char *imgname, uint64_t size, int *order) { // make sure it doesn't already exist int r = rados.stat(pool, md_oid, NULL, NULL); @@ -591,7 +594,7 @@ static int do_export(pool_t pool, string& md_oid, const char *path) } } } - r = ftruncate(fd, pos); + r = ftruncate(fd, header.image_size); if (r < 0) ret = -errno; @@ -602,8 +605,86 @@ done: return ret; } -static int do_import(pool_t pool, string& md_oid, const char *path) +static int do_import(pool_t pool, string& dir_oid, string& dir_info_oid, + const char *imgname, int order, const char *path) { + int fd = open(path, O_RDONLY); + int r; + uint64_t size; + uint64_t block_size; + struct stat stat_buf; + string md_oid; + + if (fd < 0) { + r = -errno; + cerr << "error opening " << path << std::endl; + return r; + } + + r = fstat(fd, &stat_buf); + if (r < 0) { + r = -errno; + cerr << "stat error " << path << std::endl; + return r; + } + size = (uint64_t)stat_buf.st_size; + + if (!imgname) { + imgname = strrchr(path, '/'); + if (imgname) + imgname++; + else + imgname = path; + } + md_oid = imgname; + md_oid += RBD_SUFFIX; + + r = do_create(pool, dir_oid, dir_info_oid, md_oid, imgname, size, &order); + if (r < 0) { + cerr << "image creation failed" << std::endl; + return r; + } + + block_size = 1 << order; + + /* FIXME: use fiemap to read sparse files */ + struct rbd_obj_header_ondisk header; + r = read_header(pool, md_oid, &header); + if (r < 0) { + cerr << "error reading header" << std::endl; + return r; + } + + uint64_t numseg = get_max_block(&header); + uint64_t seg_pos = 0; + for (uint64_t i=0; i