Merge remote-tracking branch 'gh/wip-rbd-tool'

This commit is contained in:
Sage Weil 2011-10-25 10:13:44 -07:00
commit cd6d70090d
9 changed files with 575 additions and 105 deletions

View File

@ -1,12 +1,12 @@
#!/bin/sh -ex
TMP_FILES="/tmp/img1 /tmp/img1.new /tmp/img2 /tmp/img2.new /tmp/img3 /tmp/img3.new /tmp/img1.snap1"
rbd rm testimg1 || true
rbd rm testimg2 || true
rbd rm testimg3 || true
rm -f /tmp/img1 /tmp/img1.new
rm -f /tmp/img2 /tmp/img2.new
rm -f /tmp/img3 /tmp/img3.new
rm -f $TMP_FILES
# create an image
dd if=/bin/sh of=/tmp/img1 bs=1k count=1 seek=10
@ -23,6 +23,10 @@ rbd snap create testimg1 --snap=snap1
rbd resize testimg1 --size=128
rbd export testimg1 /tmp/img3
# info
rbd info testimg1 | grep 'size 128 MB'
rbd info --snap=snap1 testimg1 | grep 'size 256 MB'
# make copies
rbd copy testimg1 --snap=snap1 testimg2
rbd copy testimg1 testimg3
@ -38,6 +42,16 @@ rbd export testimg3 /tmp/img3.new
cmp /tmp/img2 /tmp/img2.new
cmp /tmp/img3 /tmp/img3.new
rm /tmp/img1 /tmp/img2 /tmp/img3 /tmp/img1.new /tmp/img2.new /tmp/img3.new
# rollback
rbd snap rollback --snap=snap1 testimg1
rbd info testimg1 | grep 'size 256 MB'
rbd export testimg1 /tmp/img1.snap1
cmp /tmp/img2 /tmp/img1.snap1
# remove snapshots
rbd snap rm --snap=snap1 testimg1
rbd info --snap=snap1 testimg1 2>&1 | grep 'error setting snapshot context: error 2: No such file or directory'
rm -f $TMP_FILES
echo OK

View File

@ -0,0 +1,5 @@
#!/bin/sh -ex
wget -q https://raw.github.com/NewDreamNetwork/ceph/master/src/test/pybind/test_rbd.py
nosetests -v test_rbd
exit 0

View File

@ -1678,11 +1678,10 @@ int librados::RadosClient::clone_range(IoCtxImpl& io,
bufferlist outbl;
lock.Lock();
::SnapContext snapc;
::ObjectOperation wr;
prepare_assert_ops(&io, &wr);
wr.clone_range(src_oid, src_offset, len, dst_offset);
objecter->mutate(dst_oid, io.oloc, wr, snapc, ut, 0, onack, NULL, &ver);
objecter->mutate(dst_oid, io.oloc, wr, io.snapc, ut, 0, onack, NULL, &ver);
lock.Unlock();
mylock.Lock();
@ -1906,7 +1905,6 @@ int librados::RadosClient::aio_write_full(IoCtxImpl& io, const object_t &oid,
int librados::RadosClient::remove(IoCtxImpl& io, const object_t& oid)
{
::SnapContext snapc;
utime_t ut = ceph_clock_now(cct);
/* can't write to a snapshot */
@ -1925,7 +1923,7 @@ int librados::RadosClient::remove(IoCtxImpl& io, const object_t& oid)
lock.Lock();
objecter->remove(oid, io.oloc,
snapc, ut, 0,
io.snapc, ut, 0,
onack, NULL, &ver, pop);
lock.Unlock();
@ -1993,11 +1991,10 @@ int librados::RadosClient::tmap_update(IoCtxImpl& io, const object_t& oid, buffe
bufferlist outbl;
lock.Lock();
::SnapContext snapc;
::ObjectOperation wr;
prepare_assert_ops(&io, &wr);
wr.tmap_update(cmdbl);
objecter->mutate(oid, io.oloc, wr, snapc, ut, 0, onack, NULL, &ver);
objecter->mutate(oid, io.oloc, wr, io.snapc, ut, 0, onack, NULL, &ver);
lock.Unlock();
mylock.Lock();
@ -2028,11 +2025,10 @@ int librados::RadosClient::tmap_put(IoCtxImpl& io, const object_t& oid, bufferli
bufferlist outbl;
lock.Lock();
::SnapContext snapc;
::ObjectOperation wr;
prepare_assert_ops(&io, &wr);
wr.tmap_put(bl);
objecter->mutate(oid, io.oloc, wr, snapc, ut, 0, onack, NULL, &ver);
objecter->mutate(oid, io.oloc, wr, io.snapc, ut, 0, onack, NULL, &ver);
lock.Unlock();
mylock.Lock();

View File

@ -137,6 +137,16 @@ namespace librbd {
return CEPH_NOSNAP;
}
int get_snap_size(std::string snap_name, uint64_t *size) const
{
std::map<std::string, struct SnapInfo>::const_iterator it = snaps_by_name.find(snap_name);
if (it != snaps_by_name.end()) {
*size = it->second.size;
return 0;
}
return -ENOENT;
}
void add_snap(std::string snap_name, snap_t id, uint64_t size)
{
snapc.snaps.push_back(id);
@ -150,11 +160,12 @@ namespace librbd {
return name + RBD_SUFFIX;
}
uint64_t get_image_size() {
uint64_t get_image_size() const
{
if (snapname.length() == 0) {
return header.image_size;
} else {
map<std::string,SnapInfo>::iterator p = snaps_by_name.find(snapname);
map<std::string,SnapInfo>::const_iterator p = snaps_by_name.find(snapname);
assert(p != snaps_by_name.end());
return p->second.size;
}
@ -331,6 +342,7 @@ namespace librbd {
int info(ImageCtx *ictx, image_info_t& info, size_t image_size);
int remove(IoCtx& io_ctx, const char *imgname, ProgressContext& prog_ctx);
int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx);
int resize_helper(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx);
int snap_create(ImageCtx *ictx, const char *snap_name);
int snap_list(ImageCtx *ictx, std::vector<snap_info_t>& snaps);
int snap_rollback(ImageCtx *ictx, const char *snap_name, ProgressContext& prog_ctx);
@ -357,7 +369,7 @@ namespace librbd {
int tmap_set(IoCtx& io_ctx, const string& imgname);
int tmap_rm(IoCtx& io_ctx, const string& imgname);
int rollback_image(ImageCtx *ictx, uint64_t snapid, ProgressContext& prog_ctx);
void image_info(const rbd_obj_header_ondisk& header, image_info_t& info, size_t info_size);
void image_info(const ImageCtx& ictx, image_info_t& info, size_t info_size);
string get_block_oid(const rbd_obj_header_ondisk &header, uint64_t num);
uint64_t get_max_block(uint64_t size, int obj_order);
uint64_t get_max_block(const rbd_obj_header_ondisk &header);
@ -441,14 +453,14 @@ void init_rbd_header(struct rbd_obj_header_ondisk& ondisk,
ondisk.snap_names_len = 0;
}
void image_info(const rbd_obj_header_ondisk& header, image_info_t& info, size_t infosize)
void image_info(const ImageCtx& ictx, image_info_t& info, size_t infosize)
{
int obj_order = header.options.order;
info.size = header.image_size;
int obj_order = ictx.header.options.order;
info.size = ictx.get_image_size();
info.obj_size = 1 << obj_order;
info.num_objs = header.image_size >> obj_order;
info.num_objs = ictx.get_image_size() >> obj_order;
info.order = obj_order;
memcpy(&info.block_name_prefix, &header.block_name, RBD_MAX_BLOCK_NAME_SIZE);
memcpy(&info.block_name_prefix, &ictx.header.block_name, RBD_MAX_BLOCK_NAME_SIZE);
info.parent_pool = -1;
bzero(&info.parent_name, RBD_MAX_IMAGE_NAME_SIZE);
}
@ -828,7 +840,7 @@ int info(ImageCtx *ictx, image_info_t& info, size_t infosize)
return r;
Mutex::Locker l(ictx->lock);
image_info(ictx->header, info, infosize);
image_info(*ictx, info, infosize);
return 0;
}
@ -862,17 +874,9 @@ int remove(IoCtx& io_ctx, const char *imgname, ProgressContext& prog_ctx)
return 0;
}
int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx)
int resize_helper(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx)
{
CephContext *cct = ictx->cct;
ldout(cct, 20) << "resize " << ictx << " " << ictx->header.image_size << " -> " << size << dendl;
int r = ictx_check(ictx);
if (r < 0)
return r;
Mutex::Locker l(ictx->lock);
// trim
if (size == ictx->header.image_size) {
ldout(cct, 2) << "no change in size (" << size << " -> " << ictx->header.image_size << ")" << dendl;
return 0;
@ -890,7 +894,7 @@ int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx)
// rewrite header
bufferlist bl;
bl.append((const char *)&(ictx->header), sizeof(ictx->header));
r = ictx->md_ctx.write(ictx->md_oid(), bl, bl.length(), 0);
int r = ictx->md_ctx.write(ictx->md_oid(), bl, bl.length(), 0);
if (r == -ERANGE)
lderr(cct) << "operation might have conflicted with another client!" << dendl;
@ -901,6 +905,21 @@ int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx)
notify_change(ictx->md_ctx, ictx->md_oid(), NULL, ictx);
}
return 0;
}
int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx)
{
CephContext *cct = ictx->cct;
ldout(cct, 20) << "resize " << ictx << " " << ictx->header.image_size << " -> " << size << dendl;
int r = ictx_check(ictx);
if (r < 0)
return r;
Mutex::Locker l(ictx->lock);
resize_helper(ictx, size, prog_ctx);
ldout(cct, 2) << "done." << dendl;
return 0;
@ -1062,59 +1081,6 @@ int ictx_refresh(ImageCtx *ictx, const char *snap_name)
return 0;
}
int snap_rollback(ImageCtx *ictx, const char *snap_name, ProgressContext& prog_ctx)
{
CephContext *cct = ictx->cct;
ldout(cct, 20) << "snap_rollback " << ictx << " snap = " << snap_name << dendl;
int r = ictx_check(ictx);
if (r < 0)
return r;
Mutex::Locker l(ictx->lock);
snap_t snapid = ictx->get_snapid(snap_name);
if (snapid == CEPH_NOSNAP) {
lderr(cct) << "No such snapshot found." << dendl;
return -ENOENT;
}
r = rollback_image(ictx, snapid, prog_ctx);
if (r < 0) {
lderr(cct) << "Error rolling back image: " << cpp_strerror(-r) << dendl;
return r;
}
// refresh without setting the snapid we read from
ictx_refresh(ictx, NULL);
snap_t new_snapid = ictx->get_snapid(snap_name);
ldout(ictx->cct, 20) << "snapid is " << ictx->snapid << " new snapid is " << new_snapid << dendl;
notify_change(ictx->md_ctx, ictx->md_oid(), NULL, ictx);
return 0;
}
struct CopyProgressCtx {
CopyProgressCtx(ProgressContext &p)
: prog_ctx(p)
{
}
ImageCtx *destictx;
uint64_t src_size;
ProgressContext &prog_ctx;
};
int do_copy_extent(uint64_t offset, size_t len, const char *buf, void *data)
{
CopyProgressCtx *cp = reinterpret_cast<CopyProgressCtx*>(data);
cp->prog_ctx.update_progress(offset, cp->src_size);
int ret = 0;
if (buf) {
ret = write(cp->destictx, offset, len, buf);
}
return ret;
}
ProgressContext::~ProgressContext()
{
}
@ -1147,6 +1113,70 @@ private:
void *m_data;
};
int snap_rollback(ImageCtx *ictx, const char *snap_name, ProgressContext& prog_ctx)
{
CephContext *cct = ictx->cct;
ldout(cct, 20) << "snap_rollback " << ictx << " snap = " << snap_name << dendl;
int r = ictx_check(ictx);
if (r < 0)
return r;
Mutex::Locker l(ictx->lock);
snap_t snapid = ictx->get_snapid(snap_name);
if (snapid == CEPH_NOSNAP) {
lderr(cct) << "No such snapshot found." << dendl;
return -ENOENT;
}
uint64_t new_size = ictx->get_image_size();
ictx->get_snap_size(snap_name, &new_size);
ldout(cct, 2) << "resizing to snapshot size..." << dendl;
NoOpProgressContext no_op;
r = resize_helper(ictx, new_size, no_op);
if (r < 0) {
lderr(cct) << "Error resizing to snapshot size: "
<< cpp_strerror(-r) << dendl;
return r;
}
r = rollback_image(ictx, snapid, prog_ctx);
if (r < 0) {
lderr(cct) << "Error rolling back image: " << cpp_strerror(-r) << dendl;
return r;
}
// refresh without setting the snapid we read from
ictx_refresh(ictx, NULL);
snap_t new_snapid = ictx->get_snapid(snap_name);
ldout(cct, 20) << "snapid is " << ictx->snapid << " new snapid is " << new_snapid << dendl;
notify_change(ictx->md_ctx, ictx->md_oid(), NULL, ictx);
return r;
}
struct CopyProgressCtx {
CopyProgressCtx(ProgressContext &p)
: prog_ctx(p)
{
}
ImageCtx *destictx;
uint64_t src_size;
ProgressContext &prog_ctx;
};
int do_copy_extent(uint64_t offset, size_t len, const char *buf, void *data)
{
CopyProgressCtx *cp = reinterpret_cast<CopyProgressCtx*>(data);
cp->prog_ctx.update_progress(offset, cp->src_size);
int ret = 0;
if (buf) {
ret = write(cp->destictx, offset, len, buf);
}
return ret;
}
int copy(ImageCtx& ictx, IoCtx& dest_md_ctx, const char *destname,
ProgressContext &prog_ctx)
{
@ -1190,10 +1220,14 @@ int snap_set(ImageCtx *ictx, const char *snap_name)
return r;
Mutex::Locker l(ictx->lock);
if (snap_name)
ictx->snap_set(snap_name);
else
if (snap_name) {
r = ictx->snap_set(snap_name);
if (r < 0) {
return r;
}
} else {
ictx->snap_unset();
}
ictx->data_ctx.snap_set_read(ictx->snapid);

View File

@ -304,7 +304,6 @@ class Image(object):
:type dest_ioctx: :class:`rados.Ioctx`
:param dest_name: the name of the copy
:type dest_name: str
:returns: int - the number of bytes copied
:raises: :class:`ImageExists`
"""
if not isinstance(dest_name, str):
@ -312,7 +311,6 @@ class Image(object):
ret = self.librbd.rbd_copy(self.image, dest_ioctx.io, c_char_p(dest_name))
if ret < 0:
raise make_ex(ret, 'error copying image %s to %s' % (self.name, dest_name))
return ret
def list_snaps(self):
"""

View File

@ -56,18 +56,18 @@ void usage()
cout << "usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...\n"
<< "where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:\n"
<< " <ls | list> [pool-name] list rbd images\n"
<< " info [image-name] show information about image size,\n"
<< " info <--snap=name> [image-name] show information about image size,\n"
<< " striping, etc.\n"
<< " create [image-name] create an empty image (requires size\n"
<< " param)\n"
<< " resize [image-name] resize (expand or contract) image\n"
<< " (requires size param)\n"
<< " rm [image-name] delete an image\n"
<< " export [image-name] [dest-path] export image to file\n"
<< " export <--snap=name> [image-name] [path] export image to file\n"
<< " import [path] [dst-image] import image from file (dest defaults\n"
<< " as the filename part of file)\n"
<< " <cp | copy> [src-image] [dest-image] copy image to dest\n"
<< " <mv | rename> [src-image] [dest-image] copy image to dest\n"
<< " <cp | copy> <--snap=name> [src] [dest] copy src image to dest\n"
<< " <mv | rename> [src] [dest] rename src image to dest\n"
<< " snap ls [image-name] dump list of image snapshots\n"
<< " snap create <--snap=name> [image-name] create a snapshot\n"
<< " snap rollback <--snap=name> [image-name] rollback image head to snapshot\n"
@ -1003,12 +1003,13 @@ int main(int argc, const char **argv)
usage_exit();
}
if (opt_cmd == OPT_INFO || opt_cmd == OPT_EXPORT || opt_cmd == OPT_COPY ||
opt_cmd == OPT_SNAP_CREATE || opt_cmd == OPT_SNAP_ROLLBACK ||
opt_cmd == OPT_SNAP_REMOVE ||
opt_cmd == OPT_MAP || opt_cmd == OPT_UNMAP) {
set_pool_image_name(poolname, imgname, (char **)&poolname, (char **)&imgname, (char **)&snapname);
} else if (snapname) {
// do this unconditionally so we can parse pool/image@snapshot into
// the relevant parts
set_pool_image_name(poolname, imgname, (char **)&poolname,
(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_COPY) {
cerr << "error: snapname specified for a command that doesn't use it" << std::endl;
usage_exit();
}
@ -1053,7 +1054,7 @@ int main(int argc, const char **argv)
}
}
if (imgname &&
if (imgname && talk_to_cluster &&
(opt_cmd == OPT_RESIZE || opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST ||
opt_cmd == OPT_SNAP_CREATE || opt_cmd == OPT_SNAP_ROLLBACK ||
opt_cmd == OPT_SNAP_REMOVE || opt_cmd == OPT_EXPORT || opt_cmd == OPT_WATCH ||
@ -1065,9 +1066,10 @@ int main(int argc, const char **argv)
}
}
if (snapname) {
if (snapname && talk_to_cluster &&
(opt_cmd == OPT_INFO || opt_cmd == OPT_EXPORT || opt_cmd == OPT_COPY)) {
r = image.snap_set(snapname);
if (r < 0 && !(r == -ENOENT && opt_cmd == OPT_SNAP_CREATE)) {
if (r < 0) {
cerr << "error setting snapshot context: " << cpp_strerror(-r) << std::endl;
exit(1);
}

38
src/test/cli/rbd/help.t Normal file
View File

@ -0,0 +1,38 @@
$ rbd --help
usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...
where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:
<ls | list> [pool-name] list rbd images
info <--snap=name> [image-name] show information about image size,
striping, etc.
create [image-name] create an empty image (requires size
param)
resize [image-name] resize (expand or contract) image
(requires size param)
rm [image-name] delete an image
export <--snap=name> [image-name] [path] export image to file
import [path] [dst-image] import image from file (dest defaults
as the filename part of file)
<cp | copy> <--snap=name> [src] [dest] copy src image to dest
<mv | rename> [src] [dest] rename src image to dest
snap ls [image-name] dump list of image snapshots
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
unmap [device] unmap a rbd device that was
mapped by the kernel
Other input options:
-p, --pool <pool> source pool name
--image <image-name> image name
--dest <name> destination [pool and] image name
--snap <snapname> specify snapshot name
--dest-pool <name> destination pool name
--path <path-name> path name for import/export (if not specified)
--size <size in MB> size parameter for create and resize commands
For the map command:
--user <username> rados user to authenticate as
--secret <path> file containing secret key for use with authx

View File

@ -0,0 +1,360 @@
$ rbd resize --snap=snap1 img
error: snapname specified for a command that doesn't use it
usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...
where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:
<ls | list> [pool-name] list rbd images
info <--snap=name> [image-name] show information about image size,
striping, etc.
create [image-name] create an empty image (requires size
param)
resize [image-name] resize (expand or contract) image
(requires size param)
rm [image-name] delete an image
export <--snap=name> [image-name] [path] export image to file
import [path] [dst-image] import image from file (dest defaults
as the filename part of file)
<cp | copy> <--snap=name> [src] [dest] copy src image to dest
<mv | rename> [src] [dest] rename src image to dest
snap ls [image-name] dump list of image snapshots
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
unmap [device] unmap a rbd device that was
mapped by the kernel
Other input options:
-p, --pool <pool> source pool name
--image <image-name> image name
--dest <name> destination [pool and] image name
--snap <snapname> specify snapshot name
--dest-pool <name> destination pool name
--path <path-name> path name for import/export (if not specified)
--size <size in MB> size parameter for create and resize commands
For the map command:
--user <username> rados user to authenticate as
--secret <path> file containing secret key for use with authx
[1]
$ rbd resize img@snap
error: snapname specified for a command that doesn't use it
usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...
where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:
<ls | list> [pool-name] list rbd images
info <--snap=name> [image-name] show information about image size,
striping, etc.
create [image-name] create an empty image (requires size
param)
resize [image-name] resize (expand or contract) image
(requires size param)
rm [image-name] delete an image
export <--snap=name> [image-name] [path] export image to file
import [path] [dst-image] import image from file (dest defaults
as the filename part of file)
<cp | copy> <--snap=name> [src] [dest] copy src image to dest
<mv | rename> [src] [dest] rename src image to dest
snap ls [image-name] dump list of image snapshots
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
unmap [device] unmap a rbd device that was
mapped by the kernel
Other input options:
-p, --pool <pool> source pool name
--image <image-name> image name
--dest <name> destination [pool and] image name
--snap <snapname> specify snapshot name
--dest-pool <name> destination pool name
--path <path-name> path name for import/export (if not specified)
--size <size in MB> size parameter for create and resize commands
For the map command:
--user <username> rados user to authenticate as
--secret <path> file containing secret key for use with authx
[1]
$ rbd import --snap=snap1 /bin/ls ls
error: snapname specified for a command that doesn't use it
usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...
where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:
<ls | list> [pool-name] list rbd images
info <--snap=name> [image-name] show information about image size,
striping, etc.
create [image-name] create an empty image (requires size
param)
resize [image-name] resize (expand or contract) image
(requires size param)
rm [image-name] delete an image
export <--snap=name> [image-name] [path] export image to file
import [path] [dst-image] import image from file (dest defaults
as the filename part of file)
<cp | copy> <--snap=name> [src] [dest] copy src image to dest
<mv | rename> [src] [dest] rename src image to dest
snap ls [image-name] dump list of image snapshots
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
unmap [device] unmap a rbd device that was
mapped by the kernel
Other input options:
-p, --pool <pool> source pool name
--image <image-name> image name
--dest <name> destination [pool and] image name
--snap <snapname> specify snapshot name
--dest-pool <name> destination pool name
--path <path-name> path name for import/export (if not specified)
--size <size in MB> size parameter for create and resize commands
For the map command:
--user <username> rados user to authenticate as
--secret <path> file containing secret key for use with authx
[1]
$ rbd create --snap=snap img
error: snapname specified for a command that doesn't use it
usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...
where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:
<ls | list> [pool-name] list rbd images
info <--snap=name> [image-name] show information about image size,
striping, etc.
create [image-name] create an empty image (requires size
param)
resize [image-name] resize (expand or contract) image
(requires size param)
rm [image-name] delete an image
export <--snap=name> [image-name] [path] export image to file
import [path] [dst-image] import image from file (dest defaults
as the filename part of file)
<cp | copy> <--snap=name> [src] [dest] copy src image to dest
<mv | rename> [src] [dest] rename src image to dest
snap ls [image-name] dump list of image snapshots
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
unmap [device] unmap a rbd device that was
mapped by the kernel
Other input options:
-p, --pool <pool> source pool name
--image <image-name> image name
--dest <name> destination [pool and] image name
--snap <snapname> specify snapshot name
--dest-pool <name> destination pool name
--path <path-name> path name for import/export (if not specified)
--size <size in MB> size parameter for create and resize commands
For the map command:
--user <username> rados user to authenticate as
--secret <path> file containing secret key for use with authx
[1]
$ rbd rm --snap=snap img
error: snapname specified for a command that doesn't use it
usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...
where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:
<ls | list> [pool-name] list rbd images
info <--snap=name> [image-name] show information about image size,
striping, etc.
create [image-name] create an empty image (requires size
param)
resize [image-name] resize (expand or contract) image
(requires size param)
rm [image-name] delete an image
export <--snap=name> [image-name] [path] export image to file
import [path] [dst-image] import image from file (dest defaults
as the filename part of file)
<cp | copy> <--snap=name> [src] [dest] copy src image to dest
<mv | rename> [src] [dest] rename src image to dest
snap ls [image-name] dump list of image snapshots
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
unmap [device] unmap a rbd device that was
mapped by the kernel
Other input options:
-p, --pool <pool> source pool name
--image <image-name> image name
--dest <name> destination [pool and] image name
--snap <snapname> specify snapshot name
--dest-pool <name> destination pool name
--path <path-name> path name for import/export (if not specified)
--size <size in MB> size parameter for create and resize commands
For the map command:
--user <username> rados user to authenticate as
--secret <path> file containing secret key for use with authx
[1]
$ rbd rename --snap=snap img
error: snapname specified for a command that doesn't use it
usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...
where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:
<ls | list> [pool-name] list rbd images
info <--snap=name> [image-name] show information about image size,
striping, etc.
create [image-name] create an empty image (requires size
param)
resize [image-name] resize (expand or contract) image
(requires size param)
rm [image-name] delete an image
export <--snap=name> [image-name] [path] export image to file
import [path] [dst-image] import image from file (dest defaults
as the filename part of file)
<cp | copy> <--snap=name> [src] [dest] copy src image to dest
<mv | rename> [src] [dest] rename src image to dest
snap ls [image-name] dump list of image snapshots
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
unmap [device] unmap a rbd device that was
mapped by the kernel
Other input options:
-p, --pool <pool> source pool name
--image <image-name> image name
--dest <name> destination [pool and] image name
--snap <snapname> specify snapshot name
--dest-pool <name> destination pool name
--path <path-name> path name for import/export (if not specified)
--size <size in MB> size parameter for create and resize commands
For the map command:
--user <username> rados user to authenticate as
--secret <path> file containing secret key for use with authx
[1]
$ rbd ls --snap=snap rbd
error: snapname specified for a command that doesn't use it
usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...
where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:
<ls | list> [pool-name] list rbd images
info <--snap=name> [image-name] show information about image size,
striping, etc.
create [image-name] create an empty image (requires size
param)
resize [image-name] resize (expand or contract) image
(requires size param)
rm [image-name] delete an image
export <--snap=name> [image-name] [path] export image to file
import [path] [dst-image] import image from file (dest defaults
as the filename part of file)
<cp | copy> <--snap=name> [src] [dest] copy src image to dest
<mv | rename> [src] [dest] rename src image to dest
snap ls [image-name] dump list of image snapshots
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
unmap [device] unmap a rbd device that was
mapped by the kernel
Other input options:
-p, --pool <pool> source pool name
--image <image-name> image name
--dest <name> destination [pool and] image name
--snap <snapname> specify snapshot name
--dest-pool <name> destination pool name
--path <path-name> path name for import/export (if not specified)
--size <size in MB> size parameter for create and resize commands
For the map command:
--user <username> rados user to authenticate as
--secret <path> file containing secret key for use with authx
[1]
$ rbd snap ls --snap=snap img
error: snapname specified for a command that doesn't use it
usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...
where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:
<ls | list> [pool-name] list rbd images
info <--snap=name> [image-name] show information about image size,
striping, etc.
create [image-name] create an empty image (requires size
param)
resize [image-name] resize (expand or contract) image
(requires size param)
rm [image-name] delete an image
export <--snap=name> [image-name] [path] export image to file
import [path] [dst-image] import image from file (dest defaults
as the filename part of file)
<cp | copy> <--snap=name> [src] [dest] copy src image to dest
<mv | rename> [src] [dest] rename src image to dest
snap ls [image-name] dump list of image snapshots
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
unmap [device] unmap a rbd device that was
mapped by the kernel
Other input options:
-p, --pool <pool> source pool name
--image <image-name> image name
--dest <name> destination [pool and] image name
--snap <snapname> specify snapshot name
--dest-pool <name> destination pool name
--path <path-name> path name for import/export (if not specified)
--size <size in MB> size parameter for create and resize commands
For the map command:
--user <username> rados user to authenticate as
--secret <path> file containing secret key for use with authx
[1]
$ rbd watch --snap=snap img
error: snapname specified for a command that doesn't use it
usage: rbd [-n <auth user>] [OPTIONS] <cmd> ...
where 'pool' is a rados pool name (default is 'rbd') and 'cmd' is one of:
<ls | list> [pool-name] list rbd images
info <--snap=name> [image-name] show information about image size,
striping, etc.
create [image-name] create an empty image (requires size
param)
resize [image-name] resize (expand or contract) image
(requires size param)
rm [image-name] delete an image
export <--snap=name> [image-name] [path] export image to file
import [path] [dst-image] import image from file (dest defaults
as the filename part of file)
<cp | copy> <--snap=name> [src] [dest] copy src image to dest
<mv | rename> [src] [dest] rename src image to dest
snap ls [image-name] dump list of image snapshots
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
unmap [device] unmap a rbd device that was
mapped by the kernel
Other input options:
-p, --pool <pool> source pool name
--image <image-name> image name
--dest <name> destination [pool and] image name
--snap <snapname> specify snapshot name
--dest-pool <name> destination pool name
--path <path-name> path name for import/export (if not specified)
--size <size in MB> size parameter for create and resize commands
For the map command:
--user <username> rados user to authenticate as
--secret <path> file containing secret key for use with authx
[1]

View File

@ -4,7 +4,7 @@ import struct
from nose import with_setup
from nose.tools import eq_ as eq, assert_raises
from rados import Rados
from rbd import RBD, Image, ImageNotFound, InvalidArgument
from rbd import RBD, Image, ImageNotFound, InvalidArgument, ImageExists
rados = None
@ -130,12 +130,12 @@ class TestImage(object):
global ioctx
data = rand_data(256)
self.image.write(data, 256)
bytes_copied = self.image.copy(ioctx, IMG_NAME + '2')
self.image.copy(ioctx, IMG_NAME + '2')
assert_raises(ImageExists, self.image.copy, ioctx, IMG_NAME + '2')
copy = Image(ioctx, IMG_NAME + '2')
copy_data = copy.read(256, 256)
copy.close()
self.rbd.remove(ioctx, IMG_NAME + '2')
eq(bytes_copied, IMG_SIZE)
eq(data, copy_data)
def test_create_snap(self):
@ -191,6 +191,29 @@ class TestImage(object):
read = self.image.read(0, 256)
eq(read, '\0' * 256)
def test_rollback_with_resize(self):
read = self.image.read(0, 256)
eq(read, '\0' * 256)
data = rand_data(256)
self.image.write(data, 0)
self.image.create_snap('snap1')
read = self.image.read(0, 256)
eq(read, data)
new_size = IMG_SIZE * 2
self.image.resize(new_size)
check_stat(self.image.stat(), new_size, IMG_ORDER)
self.image.write(data, new_size - 256)
self.image.create_snap('snap2')
read = self.image.read(new_size - 256, 256)
eq(read, data)
self.image.rollback_to_snap('snap1')
check_stat(self.image.stat(), IMG_SIZE, IMG_ORDER)
assert_raises(InvalidArgument, self.image.read, new_size - 256, 256)
self.image.rollback_to_snap('snap2')
check_stat(self.image.stat(), new_size, IMG_ORDER)
read = self.image.read(new_size - 256, 256)
eq(read, data)
def test_set_snap(self):
self.image.write('\0' * 256, 0)
self.image.create_snap('snap1')