From: Sage Weil Date: Thu, 28 Mar 2013 16:26:43 +0000 (-0700) Subject: rbd: implement simple 'diff' command X-Git-Tag: v0.62~118^2~36 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fc3f4fda76c3c04c538d7f42bdebd7a5483856bf;p=ceph.git rbd: implement simple 'diff' command Report extents allocated/changed, and whether they contain data or zeros. Signed-off-by: Sage Weil --- diff --git a/src/rbd.cc b/src/rbd.cc index a338863a5d5d..1bfe3d35911a 100644 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -98,6 +98,8 @@ void usage() " (dest defaults\n" " as the filename part of file)\n" " \"-\" for stdin\n" +" diff [--from-snap ] print extents that differ since\n" +" a previous snap, or image creation\n" " export-diff [--from-snap ] \n" " export an incremental diff to\n" " path, or \"-\" for stdout\n" @@ -1135,6 +1137,26 @@ static int do_export_diff(librbd::Image& image, const char *fromsnapname, return r; } +static int diff_cb(uint64_t ofs, size_t len, bool zero, void *arg) +{ + cout << ofs << "\t" << len << "\t" + << (zero ? "zero" : "data") << "\n"; + return 0; +} + +static int do_diff(librbd::Image& image, const char *fromsnapname, + const char *endsnapname) +{ + int64_t r; + librbd::image_info_t info; + + r = image.stat(info, sizeof(info)); + if (r < 0) + return r; + + return image.diff_iterate(fromsnapname, 0, info.size, diff_cb, NULL); +} + static const char *imgname_from_path(const char *path) { const char *imgname; @@ -1893,6 +1915,7 @@ enum { OPT_RM, OPT_EXPORT, OPT_EXPORT_DIFF, + OPT_DIFF, OPT_IMPORT, OPT_IMPORT_DIFF, OPT_COPY, @@ -1938,6 +1961,8 @@ static int get_cmd(const char *cmd, bool snapcmd, bool lockcmd) return OPT_EXPORT; if (strcmp(cmd, "export-diff") == 0) return OPT_EXPORT_DIFF; + if (strcmp(cmd, "diff") == 0) + return OPT_DIFF; if (strcmp(cmd, "import") == 0) return OPT_IMPORT; if (strcmp(cmd, "import-diff") == 0) @@ -2193,6 +2218,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \ case OPT_MAP: case OPT_BENCH_WRITE: case OPT_LOCK_LIST: + case OPT_DIFF: SET_CONF_PARAM(v, &imgname, NULL, NULL); break; case OPT_UNMAP: @@ -2308,7 +2334,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \ (char **)&imgname, (char **)&snapname); if (snapname && opt_cmd != OPT_SNAP_CREATE && opt_cmd != OPT_SNAP_ROLLBACK && opt_cmd != OPT_SNAP_REMOVE && opt_cmd != OPT_INFO && - opt_cmd != OPT_EXPORT && opt_cmd != OPT_EXPORT_DIFF && opt_cmd != OPT_COPY && + opt_cmd != OPT_EXPORT && opt_cmd != OPT_EXPORT_DIFF && opt_cmd != OPT_DIFF && opt_cmd != OPT_COPY && opt_cmd != OPT_MAP && opt_cmd != OPT_CLONE && opt_cmd != OPT_SNAP_PROTECT && opt_cmd != OPT_SNAP_UNPROTECT && opt_cmd != OPT_CHILDREN) { @@ -2405,6 +2431,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \ opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST || opt_cmd == OPT_IMPORT_DIFF || opt_cmd == OPT_EXPORT || opt_cmd == OPT_EXPORT_DIFF || opt_cmd == OPT_COPY || + opt_cmd == OPT_DIFF || opt_cmd == OPT_CHILDREN || opt_cmd == OPT_LOCK_LIST)) { if (opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST || @@ -2425,6 +2452,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \ (opt_cmd == OPT_INFO || opt_cmd == OPT_EXPORT || opt_cmd == OPT_EXPORT_DIFF || + opt_cmd == OPT_DIFF || opt_cmd == OPT_COPY || opt_cmd == OPT_CHILDREN)) { r = image.snap_set(snapname); @@ -2668,6 +2696,14 @@ if (!set_conf_param(v, p1, p2, p3)) { \ } break; + case OPT_DIFF: + r = do_diff(image, fromsnapname, snapname); + if (r < 0) { + cerr << "rbd: diff error: " << cpp_strerror(-r) << std::endl; + return EXIT_FAILURE; + } + break; + case OPT_EXPORT_DIFF: if (!path) { cerr << "rbd: export-diff requires pathname" << std::endl; diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t index 25f79023b3b0..3fc81a2f31f0 100644 --- a/src/test/cli/rbd/help.t +++ b/src/test/cli/rbd/help.t @@ -20,6 +20,8 @@ (dest defaults as the filename part of file) "-" for stdin + diff [--from-snap ] print extents that differ since + a previous snap, or image creation export-diff [--from-snap ] export an incremental diff to path, or "-" for stdout