From: Sage Weil Date: Wed, 7 Apr 2010 23:37:21 +0000 (-0700) Subject: rbdtool: maintain an rbd_directory object; add --list X-Git-Tag: v0.20~96 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e5381a5c20ad2b6ed0b331ed578c4b4583afcdda;p=ceph.git rbdtool: maintain an rbd_directory object; add --list --- diff --git a/man/rbdtool.8 b/man/rbdtool.8 index f64b6af9543a..eafd08703eba 100644 --- a/man/rbdtool.8 +++ b/man/rbdtool.8 @@ -7,6 +7,7 @@ rbdtool \- manage rados block device (RBD) images [ \fB\-p\fP | \fB\-\-pool\fI pool\fR ] [ \fB\-\-create\fI imgname\fR [ \fB\-s\fI sizeinmb\fR ] ] [ \fB\-\-delete\fI imgname\fR ] +[ \fB\-\-list\fR ] .SH DESCRIPTION .B rbdtool @@ -19,8 +20,11 @@ The size of the objects the image is striped over must be a power of two. \fB\-p\fI pool\fR, \fB\-\-pool \fIpool\fR Interact with the given \fIpool\fP. Required by most commands. .TP +\fB\-\-list\fP +will list all rbd images listed in the \fIrbd_directory\fR object. +.TP \fB\-\-create \fIimgname\fP -will create a new rbd image file. You must also specify the size via \fB\-\-size\fR. +will create a new rbd image. You must also specify the size via \fB\-\-size\fR. .TP \fB\-\-size \fIsize_in_mb\fP specifies the size (in megabytes) of the new rbd image. @@ -53,3 +57,4 @@ is part of the Ceph distributed file system. Please refer to the Ceph wiki at http://ceph.newdream.net/wiki for more information. .SH SEE ALSO .BR ceph (8), rados (8) +src/ diff --git a/src/include/rbd_types.h b/src/include/rbd_types.h index 2a6d03895c07..5f9ed6dbf250 100644 --- a/src/include/rbd_types.h +++ b/src/include/rbd_types.h @@ -12,6 +12,7 @@ */ #define RBD_SUFFIX ".rbd" +#define RBD_DIRECTORY "rbd_directory" #define RBD_DEFAULT_OBJ_ORDER 22 /* 4MB */ diff --git a/src/rbdtool.cc b/src/rbdtool.cc index 79048a594bdf..fa39eaee140f 100644 --- a/src/rbdtool.cc +++ b/src/rbdtool.cc @@ -30,7 +30,7 @@ void usage() { - cout << " usage: [--create --size ] [--delete ] [-p|--pool=]" << std::endl; + cout << " usage: [--list] [--create --size ] [--delete ] [-p|--pool=]" << std::endl; exit(1); } @@ -72,7 +72,7 @@ int main(int argc, const char **argv) env_to_vec(args); common_init(args, "rbdtool", false, true); - bool opt_create = false, opt_delete = false; + bool opt_create = false, opt_delete = false, opt_list = false; char *poolname; __u64 size = 0; int order = 0; @@ -86,7 +86,9 @@ int main(int argc, const char **argv) } FOR_EACH_ARG(args) { - if (CONF_ARG_EQ("create", '\0')) { + if (CONF_ARG_EQ("list", '\0')) { + CONF_SAFE_SET_ARG_VAL(&opt_list, OPT_BOOL); + } else if (CONF_ARG_EQ("create", '\0')) { CONF_SAFE_SET_ARG_VAL(&imgname, OPT_STR); opt_create = true; } else if (CONF_ARG_EQ("delete", '\0')) { @@ -104,12 +106,13 @@ int main(int argc, const char **argv) usage(); } - if (!opt_create && !opt_delete) + if (!opt_create && !opt_delete && !opt_list) usage(); string imgmd_str = imgname; imgmd_str += RBD_SUFFIX; object_t md_oid(imgmd_str.c_str()); + object_t dir_oid(RBD_DIRECTORY); rados_pool_t pool; @@ -119,6 +122,21 @@ int main(int argc, const char **argv) exit(1); } + if (opt_list) { + bufferlist bl; + r = rados.read(pool, dir_oid, 0, bl, 0); + if (r < 0) { + cerr << "error reading rbd directory object " << dir_oid << ": " << strerror(-r) << std::endl; + exit(1); + } + bufferlist::iterator p = bl.begin(); + bufferlist header; + map m; + ::decode(header, p); + ::decode(m, p); + for (map::iterator q = m.begin(); q != m.end(); q++) + cout << q->first << std::endl; + } if (opt_create) { if (!size) { cerr << "must specify size in MB to create an rbd image" << std::endl; @@ -132,6 +150,13 @@ int main(int argc, const char **argv) } size <<= 20; // MB -> bytes + // make sure it doesn't already exist + r = rados.stat(pool, md_oid, NULL, NULL); + if (r == 0) { + cerr << "rbd image header " << md_oid << " already exists" << std::endl; + exit(1); + } + struct rbd_obj_header_ondisk header; init_rbd_header(header, size, order); @@ -139,43 +164,69 @@ int main(int argc, const char **argv) bl.append((const char *)&header, sizeof(header)); print_header(imgname, &header); + + cout << "adding rbd image to directory..." << std::endl; + bufferlist cmdbl, emptybl; + __u8 c = CEPH_OSD_TMAP_SET; + ::encode(c, cmdbl); + ::encode(imgname, cmdbl); + ::encode(emptybl, cmdbl); + r = rados.tmap_update(pool, dir_oid, cmdbl); + if (r < 0) { + cerr << "error adding img to directory: " << strerror(-r)<< std::endl; + exit(1); + } + cout << "creating rbd image..." << std::endl; r = rados.write(pool, md_oid, 0, bl, bl.length()); if (r < 0) { - cerr << "error writing header (err=" << r << ")" << std::endl; + cerr << "error writing header: " << strerror(-r) << std::endl; exit(1); } + cout << "done." << std::endl; } if (opt_delete) { struct rbd_obj_header_ondisk header; bufferlist bl; r = rados.read(pool, md_oid, 0, bl, sizeof(header)); if (r < 0) { - cerr << "error reading header " << md_oid << std::endl; + cerr << "error reading header " << md_oid << ": " << strerror(-r) << std::endl; exit(1); + } else { + bufferlist::iterator p = bl.begin(); + p.copy(sizeof(header), (char *)&header); + __u64 size = header.image_size; + __u64 numseg = size >> header.obj_order; + print_header(imgname, &header); + + cout << "removing data..." << std::endl; + for (__u64 i=0; i> header.obj_order; - print_header(imgname, &header); - cout << "removing data..." << std::endl; - for (__u64 i=0; i