Diffs records
-~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~
+
Record the all snapshots and the HEAD in this section.
+Snap Protection status
+----------------------
+
+Record the snapshot's protection status if `--export-format=2`.
+- u8: 'p'
+- le64: length of appending data (8)
+- u8: snap protection status (0 for false, 1 for true)
+
+Others
+------
+
- le64: number of diffs
- Diffs ...
#define RBD_DIFF_ZERO 'z'
#define RBD_DIFF_END 'e'
+#define RBD_SNAP_PROTECTION_STATUS 'p'
+
#define RBD_EXPORT_IMAGE_ORDER 'O'
#define RBD_EXPORT_IMAGE_FEATURES 'T'
#define RBD_EXPORT_IMAGE_STRIPE_UNIT 'U'
encode(tag, bl);
std::string to(endsnapname);
if (export_format == 2) {
- len = to.length() + 4;
- encode(len, bl);
+ len = to.length() + 4;
+ encode(len, bl);
}
encode(to, bl);
}
+ if (endsnapname && export_format == 2) {
+ tag = RBD_SNAP_PROTECTION_STATUS;
+ encode(tag, bl);
+ bool is_protected = false;
+ r = image.snap_is_protected(endsnapname, &is_protected);
+ if (r < 0) {
+ return r;
+ }
+ len = 8;
+ encode(len, bl);
+ encode(is_protected, bl);
+ }
+
tag = RBD_DIFF_IMAGE_SIZE;
encode(tag, bl);
uint64_t endsize = info.size;
return 0;
}
+static int get_snap_protection_status(ImportDiffContext *idiffctx, bool *is_protected)
+{
+ int r;
+ char buf[sizeof(__u8)];
+ r = safe_read_exact(idiffctx->fd, buf, sizeof(buf));
+ if (r < 0) {
+ return r;
+ }
+
+ *is_protected = (buf[0] != 0);
+ idiffctx->update_progress();
+
+ return 0;
+}
+
static int do_image_resize(ImportDiffContext *idiffctx)
{
int r;
// begin image import
std::string tosnap;
+ bool is_protected = false;
ImportDiffContext idiffctx(&image, fd, size, no_progress);
while (r == 0) {
__u8 tag;
r = do_image_snap_from(&idiffctx);
} else if (tag == RBD_DIFF_TO_SNAP) {
r = do_image_snap_to(&idiffctx, &tosnap);
+ } else if (tag == RBD_SNAP_PROTECTION_STATUS) {
+ r = get_snap_protection_status(&idiffctx, &is_protected);
} else if (tag == RBD_DIFF_IMAGE_SIZE) {
r = do_image_resize(&idiffctx);
} else if (tag == RBD_DIFF_WRITE || tag == RBD_DIFF_ZERO) {
int temp_r = idiffctx.throttle.wait_for_ret();
r = (r < 0) ? r : temp_r; // preserve original error
if (r == 0 && tosnap.length()) {
- idiffctx.image->snap_create(tosnap.c_str());
+ r = idiffctx.image->snap_create(tosnap.c_str());
+ if (r == 0 && is_protected) {
+ r = idiffctx.image->snap_protect(tosnap.c_str());
+ }
}
idiffctx.finish(r);