" path or \"-\" for stdin\n"
" (cp | copy) <src> <dest> copy src image to dest\n"
" (mv | rename) <src> <dest> rename src image to dest\n"
+" metadata-set <key> <value> metadata set key with value\n"
+" metadata-remove <key> metadata remove key\n"
+" metadata-list metadata list keys with values\n"
" snap ls <image-name> dump list of image snapshots\n"
" snap create <snap-name> create a snapshot\n"
" snap rollback <snap-name> rollback image to snapshot\n"
return r;
}
+static int do_metadata_list(librbd::Image& image, Formatter *f)
+{
+ map<string, string> pairs;
+ int r;
+ TextTable tbl;
+
+ r = image.metadata_list(&pairs);
+ if (r < 0)
+ return r;
+
+ if (f) {
+ f->open_object_section("metadatas");
+ } else {
+ tbl.define_column("Key", TextTable::LEFT, TextTable::LEFT);
+ tbl.define_column("Value", TextTable::LEFT, TextTable::LEFT);
+ }
+
+ if (!pairs.empty()) {
+ bool one = (pairs.size() == 1);
+
+ if (!f) {
+ cout << "There " << (one ? "is " : "are ") << pairs.size()
+ << " metadata" << (one ? "" : "s") << " on this image.\n";
+ }
+
+ for (map<string, string>::iterator it = pairs.begin();
+ it != pairs.end(); ++it) {
+ if (f) {
+ f->dump_string(it->first.c_str(), it->second);
+ } else {
+ tbl << it->first << it->second << TextTable::endrow;
+ }
+ }
+ if (!f)
+ cout << tbl;
+ }
+
+ if (f) {
+ f->close_section();
+ f->flush(cout);
+ }
+ return 0;
+}
+
+static int do_metadata_set(librbd::Image& image, const char *key,
+ const char *value)
+{
+ return image.metadata_set(key, value);
+}
+
+static int do_metadata_remove(librbd::Image& image, const char *key)
+{
+ return image.metadata_remove(key);
+}
+
static int do_copy(librbd::Image &src, librados::IoCtx& dest_pp,
const char *destname)
{
OPT_LOCK_REMOVE,
OPT_BENCH_WRITE,
OPT_MERGE_DIFF,
+ OPT_METADATA_SET,
+ OPT_METADATA_REMOVE,
+ OPT_METADATA_LIST,
};
static int get_cmd(const char *cmd, bool snapcmd, bool lockcmd)
return OPT_UNMAP;
if (strcmp(cmd, "bench-write") == 0)
return OPT_BENCH_WRITE;
+ if (strcmp(cmd, "metadata-set") == 0)
+ return OPT_METADATA_SET;
+ if (strcmp(cmd, "metadata-remove") == 0)
+ return OPT_METADATA_REMOVE;
+ if (strcmp(cmd, "metadata-list") == 0)
+ return OPT_METADATA_LIST;
} else if (snapcmd) {
if (strcmp(cmd, "create") == 0 ||
strcmp(cmd, "add") == 0)
*devpath = NULL, *lock_cookie = NULL, *lock_client = NULL,
*lock_tag = NULL, *output_format = "plain",
*fromsnapname = NULL,
- *first_diff = NULL, *second_diff = NULL;
+ *first_diff = NULL, *second_diff = NULL, *key = NULL, *value = NULL;
char *cli_map_options = NULL;
bool lflag = false;
int pretty_format = 0;
case OPT_MAP:
case OPT_BENCH_WRITE:
case OPT_LOCK_LIST:
+ case OPT_METADATA_LIST:
case OPT_DIFF:
SET_CONF_PARAM(v, &imgname, NULL, NULL);
break;
case OPT_LOCK_REMOVE:
SET_CONF_PARAM(v, &imgname, &lock_client, &lock_cookie);
break;
+ case OPT_METADATA_SET:
+ SET_CONF_PARAM(v, &imgname, &key, &value);
+ break;
+ case OPT_METADATA_REMOVE:
+ SET_CONF_PARAM(v, &imgname, &key, NULL);
+ break;
default:
assert(0);
break;
opt_cmd != OPT_INFO && opt_cmd != OPT_LIST &&
opt_cmd != OPT_SNAP_LIST && opt_cmd != OPT_LOCK_LIST &&
opt_cmd != OPT_CHILDREN && opt_cmd != OPT_DIFF &&
+ opt_cmd != OPT_METADATA_LIST && opt_cmd != OPT_DIFF &&
opt_cmd != OPT_STATUS) {
cerr << "rbd: command doesn't use output formatting"
<< std::endl;
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 ||
+ opt_cmd == OPT_METADATA_SET || opt_cmd == OPT_METADATA_LIST || opt_cmd == OPT_METADATA_REMOVE ||
opt_cmd == OPT_STATUS)) {
if (opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST ||
opt_cmd == OPT_EXPORT || opt_cmd == OPT_EXPORT || opt_cmd == OPT_COPY ||
opt_cmd == OPT_CHILDREN || opt_cmd == OPT_LOCK_LIST ||
+ opt_cmd == OPT_METADATA_LIST ||
opt_cmd == OPT_STATUS || opt_cmd == OPT_WATCH) {
r = rbd.open_read_only(io_ctx, image, imgname, NULL);
} else {
return -r;
}
break;
+
+ case OPT_METADATA_LIST:
+ r = do_metadata_list(image, formatter.get());
+ if (r < 0) {
+ cerr << "rbd: listing metadata failed: " << cpp_strerror(r) << std::endl;
+ return -r;
+ }
+ break;
+
+ case OPT_METADATA_SET:
+ r = do_metadata_set(image, key, value);
+ if (r < 0) {
+ cerr << "rbd: listing metadata failed: " << cpp_strerror(r) << std::endl;
+ return -r;
+ }
+ break;
+
+ case OPT_METADATA_REMOVE:
+ r = do_metadata_remove(image, key);
+ if (r < 0) {
+ cerr << "rbd: removing metadata failed: " << cpp_strerror(r) << std::endl;
+ return -r;
+ }
+ break;
}
return 0;