Skip to content

Commit

Permalink
rbd:export/import image-meta when we export/import an image
Browse files Browse the repository at this point in the history
when we do exporting/importing an image, we should export or import the image-meta of this image at the same time

Signed-off-by: PCzhangPC <pengcheng.zhang@easystack.cn>
  • Loading branch information
PCzhangPC committed Aug 23, 2017
1 parent 588e5d0 commit a03da79
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 2 deletions.
14 changes: 14 additions & 0 deletions doc/dev/rbd-export.rst
Expand Up @@ -65,6 +65,20 @@ Image Stripe count
- le64: length of appending data (8)
- le64: image striping count

ImageMeta Key
-------------

- u8: 'K'
- le64: length of appending data
- string: image-meta key

ImageMeta Value
---------------

- u8: 'V'
- le64: length of appending data
- string: image-meta value

Final Record
~~~~~~~~~~~~

Expand Down
6 changes: 6 additions & 0 deletions qa/workunits/rbd/import_export.sh
Expand Up @@ -79,10 +79,16 @@ if rbd help export | grep -q export-format; then
dd if=/bin/dd of=${TMPDIR}/img bs=1k count=10 seek=100
rbd import $RBD_CREATE_ARGS ${TMPDIR}/img testimg
rbd snap create testimg@snap
rbd image-meta set testimg key1 value1
IMAGEMETA_BEFORE=`rbd image-meta list testimg`
rbd export --export-format 2 testimg ${TMPDIR}/img_v2
rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import
rbd info testimg_import
rbd info testimg_import@snap
IMAGEMETA_AFTER=`rbd image-meta list testimg_import`
if [ "$IMAGEMETA_BEFORE" != "$IMAGEMETA_AFTER" ]; then
false
fi

# compare the contents between testimg and testimg_import
rbd export testimg_import ${TMPDIR}/img_import
Expand Down
2 changes: 2 additions & 0 deletions src/tools/rbd/Utils.h
Expand Up @@ -50,6 +50,8 @@ static const std::string RBD_DIFF_BANNER_V2 ("rbd diff v2\n");
#define RBD_EXPORT_IMAGE_FEATURES 'T'
#define RBD_EXPORT_IMAGE_STRIPE_UNIT 'U'
#define RBD_EXPORT_IMAGE_STRIPE_COUNT 'C'
#define RBD_EXPORT_IMAGEMETA_KEY 'K'
#define RBD_EXPORT_IMAGEMETA_VALUE 'V'
#define RBD_EXPORT_IMAGE_END 'E'

enum SnapshotPresence {
Expand Down
32 changes: 32 additions & 0 deletions src/tools/rbd/action/Export.cc
Expand Up @@ -414,6 +414,38 @@ static int do_export_v2(librbd::Image& image, librbd::image_info_t &info, int fd
::encode(length, bl);
::encode(stripe_count, bl);

//encode imageMeta key and value
std::map<std::string, bufferlist> pairs;

r = image.metadata_list("", 0, &pairs);
if (r < 0) {
std::cerr << "failed to retrieve metadata of image : " << cpp_strerror(r)
<< std::endl;
return r;
}

if (!pairs.empty()) {
for (std::map<std::string, bufferlist>::iterator it = pairs.begin();
it != pairs.end(); ++it) {
string key(it->first.c_str(), it->first.length());
string value(it->second.c_str(), it->second.length());

//encode imageMeta key
tag = RBD_EXPORT_IMAGEMETA_KEY;
length = key.length();
::encode(tag, bl);
::encode(length, bl);
bl.append(key.data());

//encode imageMeta value
tag = RBD_EXPORT_IMAGEMETA_VALUE;
length = value.length();
::encode(tag, bl);
::encode(length, bl);
bl.append(value.data());
}
}

// encode end tag
tag = RBD_EXPORT_IMAGE_END;
::encode(tag, bl);
Expand Down
57 changes: 55 additions & 2 deletions src/tools/rbd/action/Import.cc
Expand Up @@ -555,7 +555,45 @@ static int decode_and_set_image_option(int fd, uint64_t imageopt, librbd::ImageO
return 0;
}

static int do_import_header(int fd, int import_format, uint64_t &size, librbd::ImageOptions& opts)
static int read_imagemeta_key_or_value(int fd, string &val, uint64_t length)
{
int r;

char buf[length];
r = safe_read_exact(fd, buf, length);
if (r < 0) {
return r;
}

val.assign(buf, length);

return 0;
}

static int do_import_imagemeta(int import_format, librbd::Image& image,
std::map<std::string, std::string> &pairs)
{
int r = 0;

//v1 format
if (import_format == 1) {
return r;
}

if (!pairs.empty()) {
for (std::map<std::string, std::string>::iterator it = pairs.begin();
it != pairs.end(); ++it) {
r = image.metadata_set(it->first, it->second);
if (r < 0)
return r;
}
}

return r;
}

static int do_import_header(int fd, int import_format, uint64_t &size, librbd::ImageOptions& opts,
std::map<std::string, std::string> &pairs)
{
// There is no header in v1 image.
if (import_format == 1) {
Expand All @@ -578,6 +616,9 @@ static int do_import_header(int fd, int import_format, uint64_t &size, librbd::I
opts.set(RBD_IMAGE_OPTION_FORMAT, image_format);
}

string key;
string value;

while (r == 0) {
__u8 tag;
uint64_t length;
Expand All @@ -594,6 +635,11 @@ static int do_import_header(int fd, int import_format, uint64_t &size, librbd::I
r = decode_and_set_image_option(fd, RBD_IMAGE_OPTION_STRIPE_UNIT, opts);
} else if (tag == RBD_EXPORT_IMAGE_STRIPE_COUNT) {
r = decode_and_set_image_option(fd, RBD_IMAGE_OPTION_STRIPE_COUNT, opts);
} else if (tag == RBD_EXPORT_IMAGEMETA_KEY) {
r = read_imagemeta_key_or_value(fd, key, length);
} else if (tag == RBD_EXPORT_IMAGEMETA_VALUE) {
r = read_imagemeta_key_or_value(fd, value, length);
pairs[key] = value;
} else {
std::cerr << "rbd: invalid tag in image properties zone: " << tag << "Skip it."
<< std::endl;
Expand Down Expand Up @@ -743,6 +789,7 @@ static int do_import(librados::Rados &rados, librbd::RBD &rbd,
int fd, r;
struct stat stat_buf;
utils::ProgressContext pc("Importing image", no_progress);
std::map<std::string, std::string> pairs;

assert(imgname);

Expand Down Expand Up @@ -796,7 +843,7 @@ static int do_import(librados::Rados &rados, librbd::RBD &rbd,
#endif
}

r = do_import_header(fd, import_format, size, opts);
r = do_import_header(fd, import_format, size, opts, pairs);
if (r < 0) {
std::cerr << "rbd: import header failed." << std::endl;
goto done;
Expand All @@ -814,6 +861,12 @@ static int do_import(librados::Rados &rados, librbd::RBD &rbd,
goto err;
}

r = do_import_imagemeta(import_format, image, pairs);
if (r < 0) {
std::cerr << "rbd: failed to import image-meta" << std::endl;
goto err;
}

if (import_format == 1) {
r = do_import_v1(fd, image, size, imgblklen, pc, sparse_size);
} else {
Expand Down

0 comments on commit a03da79

Please sign in to comment.