.B \fBmv\fP [\fIsrc\-image\fP] [\fIdest\-image\fP]
Renames an image. Note: rename across pools is not supported.
.TP
-.B \fBmetadata-list\fP [\fIimage\-name\fP]
+.B \fBimage-meta list\fP [\fIimage\-name\fP]
Show metadata held on the image. The first column is the key
and the second column is the value.
.TP
-.B \fBmetadata-set\fP [\fIimage\-name\fP] [\fIkey\fP] [\fIvalue\fP]
+.B \fBimage-meta get\fP [\fIimage\-name\fP] [\fIkey\fP]
+Get metadata value with the key.
+.TP
+.B \fBimage-meta set\fP [\fIimage\-name\fP] [\fIkey\fP] [\fIvalue\fP]
Set metadata key with the value. They will displayed in \fImetadata-list\fP
.TP
-.B \fBmetadata-remove\fP [\fIimage\-name\fP] [\fIkey\fP]
+.B \fBimage-meta remove\fP [\fIimage\-name\fP] [\fIkey\fP]
Remove metadata key with the value.
.TP
.B \fBsnap\fP ls [\fIimage\-name\fP]
cls_method_handle_t h_metadata_set;
cls_method_handle_t h_metadata_remove;
cls_method_handle_t h_metadata_list;
+cls_method_handle_t h_metadata_get;
cls_method_handle_t h_old_snapshots_list;
cls_method_handle_t h_old_snapshot_add;
cls_method_handle_t h_old_snapshot_remove;
return 0;
}
+/**
+ * Input:
+ * @param key
+ *
+ * Output:
+ * @param metadata value associated with the key
+ * @returns 0 on success, negative error code on failure
+ */
+int metadata_get(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+ string key, value;
+
+ bufferlist::iterator iter = in->begin();
+ try {
+ ::decode(key, iter);
+ } catch (const buffer::error &err) {
+ return -EINVAL;
+ }
+
+ CLS_LOG(20, "metdata_get key=%s", key.c_str());
+
+ int r = read_key(hctx, metadata_key_for_name(key), &value);
+ if (r < 0) {
+ CLS_ERR("error get metadata: %d", r);
+ return r;
+ }
+
+ ::encode(value, *out);
+ return 0;
+}
+
/****************************** Old format *******************************/
cls_register_cxx_method(h_class, "metadata_remove",
CLS_METHOD_RD | CLS_METHOD_WR,
metadata_remove, &h_metadata_remove);
+ cls_register_cxx_method(h_class, "metadata_get",
+ CLS_METHOD_RD,
+ metadata_get, &h_metadata_get);
/* methods for the rbd_children object */
cls_register_cxx_method(h_class, "add_child",
return 0;
}
+
+ int metadata_get(librados::IoCtx *ioctx, const std::string &oid,
+ const std::string &key, string *s)
+ {
+ assert(s);
+ bufferlist in, out;
+ ::encode(key, in);
+ int r = ioctx->exec(oid, "rbd", "metadata_get", in, out);
+ if (r < 0)
+ return r;
+
+ bufferlist::iterator iter = out.begin();
+ try {
+ ::decode(*s, iter);
+ } catch (const buffer::error &err) {
+ return -EBADMSG;
+ }
+
+ return 0;
+ }
+
} // namespace cls_client
} // namespace librbd
uint64_t *stripe_unit, uint64_t *stripe_count);
int set_stripe_unit_count(librados::IoCtx *ioctx, const std::string &oid,
uint64_t stripe_unit, uint64_t stripe_count);
+ int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
+ map<string, string> *pairs);
+ int metadata_set(librados::IoCtx *ioctx, const std::string &oid,
+ const std::string &key, const std::string &data);
+ int metadata_remove(librados::IoCtx *ioctx, const std::string &oid,
+ const std::string &key);
+ int metadata_get(librados::IoCtx *ioctx, const std::string &oid,
+ const std::string &key, string *v);
// operations on rbd_id objects
int get_id(librados::IoCtx *ioctx, const std::string &oid, std::string *id);
uint8_t new_object_state,
const boost::optional<uint8_t> ¤t_object_state);
- // operations on the rbd_object_map.$image_id object
- int metadata_set(librados::IoCtx *ioctx, const std::string &oid,
- const std::string &key, const std::string &data);
- int metadata_remove(librados::IoCtx *ioctx, const std::string &oid,
- const std::string &key);
- int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
- map<string, string> *pairs);
-
// class operations on the old format, kept for
// backwards compatability
int old_snapshot_add(librados::IoCtx *ioctx, const std::string &oid,
*/
CEPH_RBD_API int rbd_invalidate_cache(rbd_image_t image);
+CEPH_RBD_API int rbd_metadata_get(rbd_image_t image, const char *key, char *value, size_t *val_len);
CEPH_RBD_API int rbd_metadata_set(rbd_image_t image, const char *key, const char *value);
CEPH_RBD_API int rbd_metadata_remove(rbd_image_t image, const char *key);
/**
*/
int invalidate_cache();
+ int metadata_get(const std::string &key, std::string *value);
int metadata_set(const std::string &key, const std::string &value);
int metadata_remove(const std::string &key);
/**
return r;
}
+ int metadata_get(ImageCtx *ictx, const string &key, string *value)
+ {
+ CephContext *cct = ictx->cct;
+ ldout(cct, 20) << "metadata_get " << ictx << " key=" << key << dendl;
+
+ int r = ictx_check(ictx);
+ if (r < 0) {
+ return r;
+ }
+
+ return cls_client::metadata_get(&ictx->md_ctx, ictx->header_oid, key, value);
+ }
+
int metadata_set(ImageCtx *ictx, const string &key, const string &value)
{
CephContext *cct = ictx->cct;
int _flush(ImageCtx *ictx);
int invalidate_cache(ImageCtx *ictx);
int metadata_list(ImageCtx *ictx, map<string, string> *pairs);
+ int metadata_get(ImageCtx *ictx, const std::string &key, std::string *value);
int metadata_set(ImageCtx *ictx, const std::string &key, const std::string &value);
int metadata_remove(ImageCtx *ictx, const std::string &key);
return r;
}
+ int Image::metadata_get(const std::string &key, std::string *value)
+ {
+ ImageCtx *ictx = (ImageCtx *)ctx;
+ tracepoint(librbd, metadata_get_enter, ictx, key.c_str());
+ int r = librbd::metadata_get(ictx, key, value);
+ if (r < 0)
+ tracepoint(librbd, metadata_get_exit, r, key.c_str(), NULL);
+ else
+ tracepoint(librbd, metadata_get_exit, r, key.c_str(), value->c_str());
+ return r;
+ }
+
int Image::metadata_set(const std::string &key, const std::string &value)
{
ImageCtx *ictx = (ImageCtx *)ctx;
return r;
}
+extern "C" int rbd_metadata_get(rbd_image_t image, const char *key, char *value, size_t *vallen)
+{
+ librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+ string val_s;
+ tracepoint(librbd, metadata_get_enter, ictx, key);
+ int r = librbd::metadata_get(ictx, key, &val_s);
+ if (r < 0) {
+ tracepoint(librbd, metadata_get_exit, r, key, NULL);
+ return r;
+ }
+ if (*vallen < val_s.size()) {
+ r = -ERANGE;
+ *vallen = val_s.size();
+ tracepoint(librbd, metadata_get_exit, r, key, NULL);
+ } else {
+ strncpy(value, val_s.c_str(), val_s.size());
+ tracepoint(librbd, metadata_get_exit, r, key, value);
+ }
+ return r;
+}
+
extern "C" int rbd_metadata_set(rbd_image_t image, const char *key, const char *value)
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
" 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"
+" image-meta list <image-name> image metadata list keys with values\n"
+" image-meta get <image-name> <key> image metadata get the value associated with the key\n"
+" image-meta set <image-name> <key> <value> image metadata set key with value\n"
+" image-meta remove <image-name> <key> image metadata remove the key and value associated\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 image.metadata_remove(key);
}
+static int do_metadata_get(librbd::Image& image, const char *key)
+{
+ string s;
+ int r = image.metadata_get(key, &s);
+ if (r < 0)
+ return r;
+ cout << s;
+ return 0;
+}
+
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_LIST,
OPT_METADATA_SET,
+ OPT_METADATA_GET,
OPT_METADATA_REMOVE,
- OPT_METADATA_LIST,
};
-static int get_cmd(const char *cmd, bool snapcmd, bool lockcmd)
+static int get_cmd(const char *cmd, bool snapcmd, bool lockcmd, bool metacmd)
{
if (!snapcmd && !lockcmd) {
if (strcmp(cmd, "ls") == 0 ||
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)
return OPT_SNAP_PROTECT;
if (strcmp(cmd, "unprotect") == 0)
return OPT_SNAP_UNPROTECT;
+ } else if (metacmd) {
+ if (strcmp(cmd, "list") == 0)
+ return OPT_METADATA_LIST;
+ if (strcmp(cmd, "set") == 0)
+ return OPT_METADATA_SET;
+ if (strcmp(cmd, "get") == 0)
+ return OPT_METADATA_GET;
+ if (strcmp(cmd, "remove") == 0)
+ return OPT_METADATA_REMOVE;
} else {
if (strcmp(cmd, "ls") == 0 ||
strcmp(cmd, "list") == 0)
cerr << "rbd: which snap command do you want?" << std::endl;
return EXIT_FAILURE;
}
- opt_cmd = get_cmd(*i, true, false);
+ opt_cmd = get_cmd(*i, true, false, false);
} else if (strcmp(*i, "lock") == 0) {
i = args.erase(i);
if (i == args.end()) {
cerr << "rbd: which lock command do you want?" << std::endl;
return EXIT_FAILURE;
}
- opt_cmd = get_cmd(*i, false, true);
+ opt_cmd = get_cmd(*i, false, true, false);
+ } else if (strcmp(*i, "image-meta") == 0) {
+ i = args.erase(i);
+ if (i == args.end()) {
+ cerr << "rbd: which image-meta command do you want?" << std::endl;
+ return EXIT_FAILURE;
+ }
+ opt_cmd = get_cmd(*i, false, false, true);
} else {
- opt_cmd = get_cmd(*i, false, false);
+ opt_cmd = get_cmd(*i, false, false, false);
}
if (opt_cmd == OPT_NO_CMD) {
cerr << "rbd: error parsing command '" << *i << "'; -h or --help for usage" << std::endl;
case OPT_METADATA_SET:
SET_CONF_PARAM(v, &imgname, &key, &value);
break;
+ case OPT_METADATA_GET:
case OPT_METADATA_REMOVE:
SET_CONF_PARAM(v, &imgname, &key, NULL);
break;
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_METADATA_SET || opt_cmd == OPT_METADATA_LIST ||
+ opt_cmd == OPT_METADATA_REMOVE || opt_cmd == OPT_METADATA_GET ||
opt_cmd == OPT_STATUS)) {
if (opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST ||
return -r;
}
break;
+
+ case OPT_METADATA_GET:
+ r = do_metadata_get(image, key);
+ if (r < 0) {
+ cerr << "rbd: getting metadata failed: " << cpp_strerror(r) << std::endl;
+ return -r;
+ }
+ break;
}
return 0;
)
)
+TRACEPOINT_EVENT(librbd, metadata_get_enter,
+ TP_ARGS(
+ void*, imagectx,
+ const char*, key),
+ TP_FIELDS(
+ ctf_integer_hex(void*, imagectx, imagectx)
+ ctf_string(key, key)
+ )
+)
+
+TRACEPOINT_EVENT(librbd, metadata_get_exit,
+ TP_ARGS(
+ int, retval,
+ const char*, key,
+ const char*, value),
+ TP_FIELDS(
+ ctf_integer(int, retval, retval)
+ ctf_string(key, key)
+ ctf_string(value, value)
+ )
+)
+
TRACEPOINT_EVENT(librbd, metadata_set_enter,
TP_ARGS(
void*, imagectx,