Merge pull request #23841 from idryomov/wip-krbd-namespaces

krbd: support for images within namespaces

Reviewed-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Ilya Dryomov 2018-09-01 11:39:40 +02:00 committed by GitHub
commit 33fea11ebf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 308 additions and 200 deletions

View File

@ -24,15 +24,27 @@ struct krbd_ctx;
int krbd_create_from_context(rados_config_t cct, struct krbd_ctx **pctx);
void krbd_destroy(struct krbd_ctx *ctx);
int krbd_map(struct krbd_ctx *ctx, const char *pool, const char *image,
const char *snap, const char *options, char **pdevnode);
int krbd_is_mapped(struct krbd_ctx *ctx, const char *pool, const char *image,
const char *snap, char **pdevnode);
int krbd_map(struct krbd_ctx *ctx,
const char *pool_name,
const char *nspace_name,
const char *image_name,
const char *snap_name,
const char *options,
char **pdevnode);
int krbd_is_mapped(struct krbd_ctx *ctx,
const char *pool_name,
const char *nspace_name,
const char *image_name,
const char *snap_name,
char **pdevnode);
int krbd_unmap(struct krbd_ctx *ctx, const char *devnode,
const char *options);
int krbd_unmap_by_spec(struct krbd_ctx *ctx, const char *pool,
const char *image, const char *snap,
int krbd_unmap_by_spec(struct krbd_ctx *ctx,
const char *pool_name,
const char *nspace_name,
const char *image_name,
const char *snap_name,
const char *options);
#ifdef __cplusplus

View File

@ -13,7 +13,7 @@
#include <errno.h>
#include <fcntl.h>
#include <iostream>
#include <map>
#include <optional>
#include <poll.h>
#include <sstream>
#include <stdio.h>
@ -49,6 +49,52 @@ struct krbd_ctx {
struct udev *udev;
};
static const std::string SNAP_HEAD_NAME("-");
struct krbd_spec {
std::string pool_name;
std::string nspace_name;
std::string image_name;
std::string snap_name;
krbd_spec(const char *pool_name, const char *nspace_name,
const char *image_name, const char *snap_name)
: pool_name(pool_name),
nspace_name(nspace_name),
image_name(image_name),
snap_name(*snap_name ? snap_name : SNAP_HEAD_NAME) { }
bool operator==(const krbd_spec& rhs) const {
return pool_name == rhs.pool_name &&
nspace_name == rhs.nspace_name &&
image_name == rhs.image_name &&
snap_name == rhs.snap_name;
}
};
std::ostream& operator<<(std::ostream& os, const krbd_spec& spec) {
os << spec.pool_name << "/";
if (!spec.nspace_name.empty())
os << spec.nspace_name << "/";
os << spec.image_name;
if (spec.snap_name != SNAP_HEAD_NAME)
os << "@" << spec.snap_name;
return os;
}
std::optional<krbd_spec> spec_from_dev(udev_device *dev) {
const char *pool_name = udev_device_get_sysattr_value(dev, "pool");
const char *nspace_name = udev_device_get_sysattr_value(dev, "pool_ns");
const char *image_name = udev_device_get_sysattr_value(dev, "name");
const char *snap_name = udev_device_get_sysattr_value(dev, "current_snap");
if (!pool_name || !image_name || !snap_name)
return std::nullopt;
return std::make_optional<krbd_spec>(
pool_name, nspace_name ?: "", image_name, snap_name);
}
static string get_kernel_rbd_name(const char *id)
{
return string("/dev/rbd") + id;
@ -109,8 +155,8 @@ static int have_minor_attr(void)
return access("/sys/module/rbd/parameters/single_major", F_OK) == 0;
}
static int build_map_buf(CephContext *cct, const char *pool, const char *image,
const char *snap, const char *options, string *pbuf)
static int build_map_buf(CephContext *cct, const krbd_spec& spec,
const char *options, string *pbuf)
{
ostringstream oss;
int r;
@ -172,15 +218,17 @@ static int build_map_buf(CephContext *cct, const char *pool, const char *image,
if (strcmp(options, "") != 0)
oss << "," << options;
if (!spec.nspace_name.empty())
oss << ",_pool_ns=" << spec.nspace_name;
oss << " " << pool << " " << image << " " << snap;
oss << " " << spec.pool_name << " " << spec.image_name << " "
<< spec.snap_name;
*pbuf = oss.str();
return 0;
}
static int wait_for_udev_add(struct udev_monitor *mon, const char *pool,
const char *image, const char *snap,
static int wait_for_udev_add(struct udev_monitor *mon, const krbd_spec& spec,
string *pname)
{
struct udev_device *bus_dev = nullptr;
@ -208,14 +256,8 @@ static int wait_for_udev_add(struct udev_monitor *mon, const char *pool,
if (!bus_dev) {
if (strcmp(udev_device_get_subsystem(dev), "rbd") == 0) {
const char *this_pool = udev_device_get_sysattr_value(dev, "pool");
const char *this_image = udev_device_get_sysattr_value(dev, "name");
const char *this_snap = udev_device_get_sysattr_value(dev,
"current_snap");
if (this_pool && strcmp(this_pool, pool) == 0 &&
this_image && strcmp(this_image, image) == 0 &&
this_snap && strcmp(this_snap, snap) == 0) {
auto cur_spec = spec_from_dev(dev);
if (cur_spec && *cur_spec == spec) {
bus_dev = dev;
continue;
}
@ -250,8 +292,8 @@ static int wait_for_udev_add(struct udev_monitor *mon, const char *pool,
return 0;
}
static int do_map(struct udev *udev, const char *pool, const char *image,
const char *snap, const string& buf, string *pname)
static int do_map(struct udev *udev, const krbd_spec& spec, const string& buf,
string *pname)
{
struct udev_monitor *mon;
int r;
@ -278,7 +320,7 @@ static int do_map(struct udev *udev, const char *pool, const char *image,
goto out_mon;
}
r = wait_for_udev_add(mon, pool, image, snap, pname);
r = wait_for_udev_add(mon, spec, pname);
if (r < 0) {
cerr << "rbd: wait failed" << std::endl;
goto out_mon;
@ -289,16 +331,13 @@ out_mon:
return r;
}
static int map_image(struct krbd_ctx *ctx, const char *pool, const char *image,
const char *snap, const char *options, string *pname)
static int map_image(struct krbd_ctx *ctx, const krbd_spec& spec,
const char *options, string *pname)
{
string buf;
int r;
if (strcmp(snap, "") == 0)
snap = "-";
r = build_map_buf(ctx->cct, pool, image, snap, options, &buf);
r = build_map_buf(ctx->cct, spec, options, &buf);
if (r < 0)
return r;
@ -322,7 +361,7 @@ static int map_image(struct krbd_ctx *ctx, const char *pool, const char *image,
}
}
return do_map(ctx->udev, pool, image, snap, buf, pname);
return do_map(ctx->udev, spec, buf, pname);
}
static int devno_to_krbd_id(struct udev *udev, dev_t devno, string *pid)
@ -379,36 +418,85 @@ out_enm:
return r;
}
static int enumerate_devices(struct udev_enumerate *enm, const char *pool,
const char *image, const char *snap)
static int __enumerate_devices(struct udev *udev, const krbd_spec& spec,
bool match_nspace, struct udev_enumerate **penm)
{
struct udev_enumerate *enm;
int r;
enm = udev_enumerate_new(udev);
if (!enm)
return -ENOMEM;
r = udev_enumerate_add_match_subsystem(enm, "rbd");
if (r < 0)
return r;
goto out_enm;
r = udev_enumerate_add_match_sysattr(enm, "pool", pool);
r = udev_enumerate_add_match_sysattr(enm, "pool", spec.pool_name.c_str());
if (r < 0)
return r;
goto out_enm;
r = udev_enumerate_add_match_sysattr(enm, "name", image);
if (match_nspace) {
r = udev_enumerate_add_match_sysattr(enm, "pool_ns",
spec.nspace_name.c_str());
} else {
/*
* Match _only_ devices that don't have pool_ns attribute.
* If the kernel supports namespaces, the result will be empty.
*/
r = udev_enumerate_add_nomatch_sysattr(enm, "pool_ns", nullptr);
}
if (r < 0)
return r;
goto out_enm;
r = udev_enumerate_add_match_sysattr(enm, "current_snap", snap);
r = udev_enumerate_add_match_sysattr(enm, "name", spec.image_name.c_str());
if (r < 0)
return r;
goto out_enm;
r = udev_enumerate_add_match_sysattr(enm, "current_snap",
spec.snap_name.c_str());
if (r < 0)
goto out_enm;
r = udev_enumerate_scan_devices(enm);
if (r < 0)
goto out_enm;
*penm = enm;
return 0;
out_enm:
udev_enumerate_unref(enm);
return r;
}
static int enumerate_devices(struct udev *udev, const krbd_spec& spec,
struct udev_enumerate **penm)
{
struct udev_enumerate *enm;
int r;
r = __enumerate_devices(udev, spec, true, &enm);
if (r < 0)
return r;
/*
* If no namespace is set, try again with match_nspace=false to
* handle older kernels. On a newer kernel the result will remain
* the same (i.e. empty).
*/
if (!udev_enumerate_get_list_entry(enm) && spec.nspace_name.empty()) {
udev_enumerate_unref(enm);
r = __enumerate_devices(udev, spec, false, &enm);
if (r < 0)
return r;
}
*penm = enm;
return 0;
}
static int spec_to_devno_and_krbd_id(struct udev *udev, const char *pool,
const char *image, const char *snap,
static int spec_to_devno_and_krbd_id(struct udev *udev, const krbd_spec& spec,
dev_t *pdevno, string *pid)
{
struct udev_enumerate *enm;
@ -418,13 +506,9 @@ static int spec_to_devno_and_krbd_id(struct udev *udev, const char *pool,
string err;
int r;
enm = udev_enumerate_new(udev);
if (!enm)
return -ENOMEM;
r = enumerate_devices(enm, pool, image, snap);
r = enumerate_devices(udev, spec, &enm);
if (r < 0)
goto out_enm;
return r;
l = udev_enumerate_get_list_entry(enm);
if (!l) {
@ -459,8 +543,7 @@ static int spec_to_devno_and_krbd_id(struct udev *udev, const char *pool,
* ran map.
*/
if (udev_list_entry_get_next(l))
cerr << "rbd: " << pool << "/" << image << "@" << snap
<< ": mapped more than once, unmapping "
cerr << "rbd: " << spec << ": mapped more than once, unmapping "
<< get_kernel_rbd_name(udev_device_get_sysname(dev))
<< " only" << std::endl;
@ -603,22 +686,18 @@ static int unmap_image(struct krbd_ctx *ctx, const char *devnode,
return do_unmap(ctx->udev, wholedevno, build_unmap_buf(id, options));
}
static int unmap_image(struct krbd_ctx *ctx, const char *pool,
const char *image, const char *snap,
static int unmap_image(struct krbd_ctx *ctx, const krbd_spec& spec,
const char *options)
{
dev_t devno = 0;
string id;
int r;
if (!snap)
snap = "-";
r = spec_to_devno_and_krbd_id(ctx->udev, pool, image, snap, &devno, &id);
r = spec_to_devno_and_krbd_id(ctx->udev, spec, &devno, &id);
if (r < 0) {
if (r == -ENOENT) {
cerr << "rbd: " << pool << "/" << image << "@" << snap
<< ": not a mapped image or snapshot" << std::endl;
cerr << "rbd: " << spec << ": not a mapped image or snapshot"
<< std::endl;
r = -EINVAL;
}
return r;
@ -631,24 +710,24 @@ static bool dump_one_image(Formatter *f, TextTable *tbl,
struct udev_device *dev)
{
const char *id = udev_device_get_sysname(dev);
const char *pool = udev_device_get_sysattr_value(dev, "pool");
const char *image = udev_device_get_sysattr_value(dev, "name");
const char *snap = udev_device_get_sysattr_value(dev, "current_snap");
auto spec = spec_from_dev(dev);
string kname = get_kernel_rbd_name(id);
if (!pool || !image || !snap)
if (!spec)
return false;
if (f) {
f->open_object_section("device");
f->dump_string("id", id);
f->dump_string("pool", pool);
f->dump_string("name", image);
f->dump_string("snap", snap);
f->dump_string("pool", spec->pool_name);
f->dump_string("namespace", spec->nspace_name);
f->dump_string("name", spec->image_name);
f->dump_string("snap", spec->snap_name);
f->dump_string("device", kname);
f->close_section();
} else {
*tbl << id << pool << image << snap << kname << TextTable::endrow;
*tbl << id << spec->pool_name << spec->nspace_name << spec->image_name
<< spec->snap_name << kname << TextTable::endrow;
}
return true;
@ -699,6 +778,7 @@ int dump_images(struct krbd_ctx *ctx, Formatter *f)
} else {
tbl.define_column("id", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("pool", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("namespace", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("image", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("snap", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("device", TextTable::LEFT, TextTable::LEFT);
@ -717,23 +797,16 @@ int dump_images(struct krbd_ctx *ctx, Formatter *f)
return r;
}
static int is_mapped_image(struct udev *udev, const char *pool,
const char *image, const char *snap, string *pname)
static int is_mapped_image(struct udev *udev, const krbd_spec& spec,
string *pname)
{
struct udev_enumerate *enm;
struct udev_list_entry *l;
int r;
if (strcmp(snap, "") == 0)
snap = "-";
enm = udev_enumerate_new(udev);
if (!enm)
return -ENOMEM;
r = enumerate_devices(enm, pool, image, snap);
r = enumerate_devices(udev, spec, &enm);
if (r < 0)
goto out_enm;
return r;
l = udev_enumerate_get_list_entry(enm);
if (l) {
@ -783,15 +856,20 @@ extern "C" void krbd_destroy(struct krbd_ctx *ctx)
delete ctx;
}
extern "C" int krbd_map(struct krbd_ctx *ctx, const char *pool,
const char *image, const char *snap,
const char *options, char **pdevnode)
extern "C" int krbd_map(struct krbd_ctx *ctx,
const char *pool_name,
const char *nspace_name,
const char *image_name,
const char *snap_name,
const char *options,
char **pdevnode)
{
krbd_spec spec(pool_name, nspace_name, image_name, snap_name);
string name;
char *devnode;
int r;
r = map_image(ctx, pool, image, snap, options, &name);
r = map_image(ctx, spec, options, &name);
if (r < 0)
return r;
@ -809,11 +887,15 @@ extern "C" int krbd_unmap(struct krbd_ctx *ctx, const char *devnode,
return unmap_image(ctx, devnode, options);
}
extern "C" int krbd_unmap_by_spec(struct krbd_ctx *ctx, const char *pool,
const char *image, const char *snap,
extern "C" int krbd_unmap_by_spec(struct krbd_ctx *ctx,
const char *pool_name,
const char *nspace_name,
const char *image_name,
const char *snap_name,
const char *options)
{
return unmap_image(ctx, pool, image, snap, options);
krbd_spec spec(pool_name, nspace_name, image_name, snap_name);
return unmap_image(ctx, spec, options);
}
int krbd_showmapped(struct krbd_ctx *ctx, Formatter *f)
@ -821,15 +903,19 @@ int krbd_showmapped(struct krbd_ctx *ctx, Formatter *f)
return dump_images(ctx, f);
}
extern "C" int krbd_is_mapped(struct krbd_ctx *ctx, const char *pool,
const char *image, const char *snap,
extern "C" int krbd_is_mapped(struct krbd_ctx *ctx,
const char *pool_name,
const char *nspace_name,
const char *image_name,
const char *snap_name,
char **pdevnode)
{
krbd_spec spec(pool_name, nspace_name, image_name, snap_name);
string name;
char *devnode;
int r;
r = is_mapped_image(ctx->udev, pool, image, snap, &name);
r = is_mapped_image(ctx->udev, spec, &name);
if (r <= 0) /* error or not mapped */
return r;

View File

@ -30,8 +30,8 @@ Unmap by device
Unmap by device (img is already mapped):
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
$ sudo rbd device unmap $DEV
$ rbd device list
@ -39,15 +39,15 @@ Unmap by device partition:
$ DEV=$(sudo rbd device map img)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
$ sudo rbd device unmap ${DEV}p1
$ rbd device list
$ DEV=$(sudo rbd device map img)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
$ sudo rbd device unmap ${DEV}p5
$ rbd device list
@ -84,16 +84,16 @@ img:
$ sudo rbd device map img
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
$ sudo rbd device unmap img
$ rbd device list
$ sudo rbd device map img
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
$ sudo rbd --image img device unmap
$ rbd device list
@ -102,24 +102,24 @@ img@snap:
$ sudo rbd device map img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd device unmap img@snap
$ rbd device list
$ sudo rbd device map img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd --snap snap device unmap img
$ rbd device list
$ sudo rbd device map img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd --image img --snap snap device unmap
$ rbd device list
@ -128,32 +128,32 @@ pool/img@snap, default pool:
$ sudo rbd device map rbd/img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd device unmap rbd/img@snap
$ rbd device list
$ sudo rbd device map rbd/img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd --pool rbd device unmap img@snap
$ rbd device list
$ sudo rbd device map rbd/img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd --pool rbd --snap snap device unmap img
$ rbd device list
$ sudo rbd device map rbd/img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd --pool rbd --image img --snap snap device unmap
$ rbd device list
@ -162,44 +162,44 @@ pool/img@snap, custom pool:
$ sudo rbd device map custom/img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? custom img snap /dev/rbd? (glob)
id pool namespace image snap device
? custom img snap /dev/rbd? (glob)
$ sudo rbd device unmap custom/img@snap
$ rbd device list
$ sudo rbd device map custom/img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? custom img snap /dev/rbd? (glob)
id pool namespace image snap device
? custom img snap /dev/rbd? (glob)
$ sudo rbd --pool custom device unmap img@snap
$ rbd device list
$ sudo rbd device map custom/img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? custom img snap /dev/rbd? (glob)
id pool namespace image snap device
? custom img snap /dev/rbd? (glob)
$ sudo rbd --pool custom --snap snap device unmap img
$ rbd device list
$ sudo rbd device map custom/img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? custom img snap /dev/rbd? (glob)
id pool namespace image snap device
? custom img snap /dev/rbd? (glob)
$ sudo rbd --pool custom --image img --snap snap device unmap
$ rbd device list
Not a mapped spec - random junk (which gets interpreted as a spec):
$ sudo rbd device unmap foobar
rbd: rbd/foobar@-: not a mapped image or snapshot
rbd: rbd/foobar: not a mapped image or snapshot
rbd: unmap failed: (22) Invalid argument
[22]
$ sudo rbd --image foobar device unmap
rbd: rbd/foobar@-: not a mapped image or snapshot
rbd: rbd/foobar: not a mapped image or snapshot
rbd: unmap failed: (22) Invalid argument
[22]
@ -209,7 +209,7 @@ Not a mapped spec - spec that's just been unmapped:
/dev/rbd? (glob)
$ sudo rbd device unmap img
$ sudo rbd device unmap img
rbd: rbd/img@-: not a mapped image or snapshot
rbd: rbd/img: not a mapped image or snapshot
rbd: unmap failed: (22) Invalid argument
[22]
@ -238,13 +238,13 @@ Unmap img first:
$ sudo rbd device map anotherimg
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
? rbd anotherimg - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
? rbd anotherimg - /dev/rbd? (glob)
$ sudo rbd device unmap img
$ rbd device list
id pool image snap device
? rbd anotherimg - /dev/rbd? (glob)
id pool namespace image snap device
? rbd anotherimg - /dev/rbd? (glob)
$ sudo rbd device unmap anotherimg
$ rbd device list
@ -255,13 +255,13 @@ Unmap anotherimg first:
$ sudo rbd device map anotherimg
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
? rbd anotherimg - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
? rbd anotherimg - /dev/rbd? (glob)
$ sudo rbd device unmap anotherimg
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
$ sudo rbd device unmap img
$ rbd device list
@ -276,13 +276,13 @@ Unmap the image first:
$ sudo rbd device map img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
? rbd img snap /dev/rbd? (glob)
$ sudo rbd device unmap img
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd device unmap img@snap
$ rbd device list
@ -293,13 +293,13 @@ Unmap the snap first:
$ sudo rbd device map img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
? rbd img snap /dev/rbd? (glob)
$ sudo rbd device unmap img@snap
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
$ sudo rbd device unmap img
$ rbd device list
@ -314,13 +314,13 @@ Unmap snap first:
$ sudo rbd device map custom/img@anothersnap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? custom img snap /dev/rbd? (glob)
? custom img anothersnap /dev/rbd? (glob)
id pool namespace image snap device
? custom img snap /dev/rbd? (glob)
? custom img anothersnap /dev/rbd? (glob)
$ sudo rbd device unmap custom/img@snap
$ rbd device list
id pool image snap device
? custom img anothersnap /dev/rbd? (glob)
id pool namespace image snap device
? custom img anothersnap /dev/rbd? (glob)
$ sudo rbd device unmap custom/img@anothersnap
$ rbd device list
@ -331,13 +331,13 @@ Unmap anothersnap first:
$ sudo rbd device map custom/img@anothersnap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? custom img snap /dev/rbd? (glob)
? custom img anothersnap /dev/rbd? (glob)
id pool namespace image snap device
? custom img snap /dev/rbd? (glob)
? custom img anothersnap /dev/rbd? (glob)
$ sudo rbd device unmap custom/img@anothersnap
$ rbd device list
id pool image snap device
? custom img snap /dev/rbd? (glob)
id pool namespace image snap device
? custom img snap /dev/rbd? (glob)
$ sudo rbd device unmap custom/img@snap
$ rbd device list
@ -352,13 +352,13 @@ img:
$ sudo rbd device map custom/img
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
? custom img - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
? custom img - /dev/rbd? (glob)
$ sudo rbd device unmap img
$ rbd device list
id pool image snap device
? custom img - /dev/rbd? (glob)
id pool namespace image snap device
? custom img - /dev/rbd? (glob)
$ sudo rbd device unmap custom/img
$ rbd device list
@ -369,13 +369,13 @@ img@snap:
$ sudo rbd device map custom/img@snap
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
? custom img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
? custom img snap /dev/rbd? (glob)
$ sudo rbd device unmap custom/img@snap
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd device unmap img@snap
$ rbd device list
@ -391,14 +391,14 @@ img:
rbd: warning: image already mapped as /dev/rbd? (glob)
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
? rbd img - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
? rbd img - /dev/rbd? (glob)
$ sudo rbd device unmap img
rbd: rbd/img@-: mapped more than once, unmapping /dev/rbd? only (glob)
rbd: rbd/img: mapped more than once, unmapping /dev/rbd? only (glob)
$ rbd device list
id pool image snap device
? rbd img - /dev/rbd? (glob)
id pool namespace image snap device
? rbd img - /dev/rbd? (glob)
$ sudo rbd device unmap img
$ rbd device list
@ -410,14 +410,14 @@ img@snap:
rbd: warning: image already mapped as /dev/rbd? (glob)
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
? rbd img snap /dev/rbd? (glob)
$ sudo rbd device unmap img@snap
rbd: rbd/img@snap: mapped more than once, unmapping /dev/rbd? only (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd device unmap img@snap
$ rbd device list
@ -429,14 +429,14 @@ pool/img@snap, default pool:
rbd: warning: image already mapped as /dev/rbd? (glob)
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
? rbd img snap /dev/rbd? (glob)
$ sudo rbd device unmap rbd/img@snap
rbd: rbd/img@snap: mapped more than once, unmapping /dev/rbd? only (glob)
$ rbd device list
id pool image snap device
? rbd img snap /dev/rbd? (glob)
id pool namespace image snap device
? rbd img snap /dev/rbd? (glob)
$ sudo rbd device unmap rbd/img@snap
$ rbd device list
@ -448,14 +448,14 @@ pool/img@snap, custom pool:
rbd: warning: image already mapped as /dev/rbd? (glob)
/dev/rbd? (glob)
$ rbd device list
id pool image snap device
? custom img snap /dev/rbd? (glob)
? custom img snap /dev/rbd? (glob)
id pool namespace image snap device
? custom img snap /dev/rbd? (glob)
? custom img snap /dev/rbd? (glob)
$ sudo rbd device unmap custom/img@snap
rbd: custom/img@snap: mapped more than once, unmapping /dev/rbd? only (glob)
$ rbd device list
id pool image snap device
? custom img snap /dev/rbd? (glob)
id pool namespace image snap device
? custom img snap /dev/rbd? (glob)
$ sudo rbd device unmap custom/img@snap
$ rbd device list

View File

@ -968,7 +968,7 @@ krbd_open(const char *name, struct rbd_ctx *ctx)
if (ret < 0)
return ret;
ret = krbd_map(krbd, pool, name, "", "", &devnode);
ret = krbd_map(krbd, pool, "", name, "", "", &devnode);
if (ret < 0) {
prt("krbd_map(%s) failed\n", name);
return ret;

View File

@ -234,8 +234,11 @@ static int get_unsupported_features(librbd::Image &image,
* based on errno return by krbd_map(). also note that even if some librbd calls
* fail, we at least dump the "try dmesg..." message to aid debugging.
*/
static void print_error_description(const char *poolname, const char *imgname,
const char *snapname, int maperrno)
static void print_error_description(const char *poolname,
const char *nspace_name,
const char *imgname,
const char *snapname,
int maperrno)
{
int r;
uint8_t oldformat;
@ -246,7 +249,7 @@ static void print_error_description(const char *poolname, const char *imgname,
if (maperrno == -ENOENT)
goto done;
r = utils::init_and_open_image(poolname, "", imgname, "", snapname,
r = utils::init_and_open_image(poolname, nspace_name, imgname, "", snapname,
true, &rados, &ioctx, &image);
if (r < 0)
goto done;
@ -276,10 +279,12 @@ static void print_error_description(const char *poolname, const char *imgname,
} else {
std::cout << "You can disable features unsupported by the kernel "
<< "with \"rbd feature disable ";
if (poolname != utils::get_default_pool_name()) {
if (poolname != utils::get_default_pool_name() || *nspace_name) {
std::cout << poolname << "/";
}
if (*nspace_name) {
std::cout << nspace_name << "/";
}
std::cout << imgname;
}
} else {
@ -301,8 +306,8 @@ static void print_error_description(const char *poolname, const char *imgname,
std::cout << "In some cases useful info is found in syslog - try \"dmesg | tail\"." << std::endl;
}
static int do_kernel_map(const char *poolname, const char *imgname,
const char *snapname)
static int do_kernel_map(const char *poolname, const char *nspace_name,
const char *imgname, const char *snapname)
{
#if defined(WITH_KRBD)
struct krbd_ctx *krbd;
@ -329,7 +334,7 @@ static int do_kernel_map(const char *poolname, const char *imgname,
}
}
r = krbd_is_mapped(krbd, poolname, imgname, snapname, &devnode);
r = krbd_is_mapped(krbd, poolname, nspace_name, imgname, snapname, &devnode);
if (r < 0) {
std::cerr << "rbd: warning: can't get image map information: "
<< cpp_strerror(r) << std::endl;
@ -339,9 +344,10 @@ static int do_kernel_map(const char *poolname, const char *imgname,
free(devnode);
}
r = krbd_map(krbd, poolname, imgname, snapname, oss.str().c_str(), &devnode);
r = krbd_map(krbd, poolname, nspace_name, imgname, snapname,
oss.str().c_str(), &devnode);
if (r < 0) {
print_error_description(poolname, imgname, snapname, r);
print_error_description(poolname, nspace_name, imgname, snapname, r);
goto out;
}
@ -358,7 +364,8 @@ out:
}
static int do_kernel_unmap(const char *dev, const char *poolname,
const char *imgname, const char *snapname)
const char *nspace_name, const char *imgname,
const char *snapname)
{
#if defined(WITH_KRBD)
struct krbd_ctx *krbd;
@ -378,7 +385,7 @@ static int do_kernel_unmap(const char *dev, const char *poolname,
if (dev)
r = krbd_unmap(krbd, dev, oss.str().c_str());
else
r = krbd_unmap_by_spec(krbd, poolname, imgname, snapname,
r = krbd_unmap_by_spec(krbd, poolname, nspace_name, imgname, snapname,
oss.str().c_str());
krbd_destroy(krbd);
@ -411,10 +418,11 @@ int execute_map(const po::variables_map &vm,
const std::vector<std::string> &ceph_global_init_args) {
size_t arg_index = 0;
std::string pool_name;
std::string nspace_name;
std::string image_name;
std::string snap_name;
int r = utils::get_pool_image_snapshot_names(
vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr,
vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &nspace_name,
&image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED,
utils::SPEC_VALIDATION_NONE);
if (r < 0) {
@ -448,7 +456,8 @@ int execute_map(const po::variables_map &vm,
utils::init_context();
r = do_kernel_map(pool_name.c_str(), image_name.c_str(), snap_name.c_str());
r = do_kernel_map(pool_name.c_str(), nspace_name.c_str(), image_name.c_str(),
snap_name.c_str());
if (r < 0) {
std::cerr << "rbd: map failed: " << cpp_strerror(r) << std::endl;
return r;
@ -466,12 +475,13 @@ int execute_unmap(const po::variables_map &vm,
size_t arg_index = 0;
std::string pool_name;
std::string nspace_name;
std::string image_name;
std::string snap_name;
int r;
if (device_name.empty()) {
r = utils::get_pool_image_snapshot_names(
vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr,
vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &nspace_name,
&image_name, &snap_name, false, utils::SNAPSHOT_PRESENCE_PERMITTED,
utils::SPEC_VALIDATION_NONE);
if (r < 0) {
@ -498,8 +508,8 @@ int execute_unmap(const po::variables_map &vm,
utils::init_context();
r = do_kernel_unmap(device_name.empty() ? nullptr : device_name.c_str(),
pool_name.c_str(), image_name.c_str(),
snap_name.empty() ? nullptr : snap_name.c_str());
pool_name.c_str(), nspace_name.c_str(),
image_name.c_str(), snap_name.c_str());
if (r < 0) {
std::cerr << "rbd: unmap failed: " << cpp_strerror(r) << std::endl;
return r;