Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rbd-ggate: small fixes and improvements #19679

Merged
merged 4 commits into from
Dec 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 27 additions & 7 deletions qa/workunits/rbd/rbd-ggate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,23 @@ expect_false _sudo rbd-ggate map INVALIDIMAGE

# map test using the first unused device
DEV=`_sudo rbd-ggate map ${POOL}/${IMAGE}`
_sudo rbd-ggate list | grep "^${DEV}$"
_sudo rbd-ggate list | grep " ${DEV} *$"

# map test specifying the device
expect_false _sudo rbd-ggate --device ${DEV} map ${POOL}/${IMAGE}
dev1=${DEV}
_sudo rbd-ggate unmap ${DEV}
_sudo rbd-ggate list | expect_false grep "^${DEV}$"
_sudo rbd-ggate list | expect_false grep " ${DEV} *$"
DEV=
# XXX: race possible when the device is reused by other process
DEV=`_sudo rbd-ggate --device ${dev1} map ${POOL}/${IMAGE}`
[ "${DEV}" = "${dev1}" ]
_sudo rbd-ggate list | grep "^${DEV}$"
_sudo rbd-ggate list | grep " ${DEV} *$"

# list format test
expect_false _sudo rbd-ggate --format INVALID list
_sudo rbd-ggate --format json --pretty-format list
_sudo rbd-ggate --format xml list

# read test
[ "`dd if=${DATA} bs=1M | md5`" = "`_sudo dd if=${DEV} bs=1M | md5`" ]
Expand Down Expand Up @@ -137,9 +142,9 @@ rbd info ${POOL}/${IMAGE}
if [ -z "$RBD_GGATE_RESIZE_SUPPORTED" ]; then
# XXX: ggate device resize is not supported by vanila kernel.
# rbd-ggate should terminate when detecting resize.
_sudo rbd-ggate list | expect_false grep "^${DEV}$"
_sudo rbd-ggate list | expect_false grep " ${DEV} *$"
else
_sudo rbd-ggate list | grep "^${DEV}$"
_sudo rbd-ggate list | grep " ${DEV} *$"
size2=$(geom gate list ${devname} | awk '$1 ~ /Mediasize:/ {print $2}')
test -n "${size2}"
test ${size2} -eq $((size * 2))
Expand All @@ -161,7 +166,7 @@ DEV=
# read-only option test
DEV=`_sudo rbd-ggate map --read-only ${POOL}/${IMAGE}`
devname=$(basename ${DEV})
_sudo rbd-ggate list | grep "^${DEV}$"
_sudo rbd-ggate list | grep " ${DEV} *$"
access=$(geom gate list ${devname} | awk '$1 == "access:" {print $2}')
test "${access}" = "read-only"
_sudo dd if=${DEV} of=/dev/null bs=1M
Expand All @@ -170,7 +175,7 @@ _sudo rbd-ggate unmap ${DEV}

# exclusive option test
DEV=`_sudo rbd-ggate map --exclusive ${POOL}/${IMAGE}`
_sudo rbd-ggate list | grep "^${DEV}$"
_sudo rbd-ggate list | grep " ${DEV} *$"
_sudo dd if=${DATA} of=${DEV} bs=1M
_sudo sync
expect_false timeout 10 \
Expand All @@ -179,4 +184,19 @@ _sudo rbd-ggate unmap ${DEV}
DEV=
rbd bench -p ${POOL} ${IMAGE} --io-type=write --io-size=1024 --io-total=1024

# unmap by image name test
DEV=`_sudo rbd-ggate map ${POOL}/${IMAGE}`
_sudo rbd-ggate list | grep " ${DEV} *$"
_sudo rbd-ggate unmap "${POOL}/${IMAGE}"
rbd-ggate list-mapped | expect_false grep " ${DEV} *$"
DEV=

# map/unmap snap test
rbd snap create ${POOL}/${IMAGE}@snap
DEV=`_sudo rbd-ggate map ${POOL}/${IMAGE}@snap`
_sudo rbd-ggate list | grep " ${DEV} *$"
_sudo rbd-ggate unmap "${POOL}/${IMAGE}@snap"
rbd-ggate list-mapped | expect_false grep " ${DEV} *$"
DEV=

echo OK
79 changes: 56 additions & 23 deletions src/tools/rbd/action/Ggate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,49 @@ static int call_ggate_cmd(const po::variables_map &vm,
return 0;
}

int get_image_or_snap_spec(const po::variables_map &vm, std::string *spec) {
size_t arg_index = 0;
std::string pool_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, &image_name,
&snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED,
utils::SPEC_VALIDATION_NONE);
if (r < 0) {
return r;
}

spec->append(pool_name);
spec->append("/");
spec->append(image_name);
if (!snap_name.empty()) {
spec->append("@");
spec->append(snap_name);
}

return 0;
}

void get_list_arguments(po::options_description *positional,
po::options_description *options)
{ }
po::options_description *options) {
at::add_format_options(options);
}

int execute_list(const po::variables_map &vm)
{
std::vector<const char*> args;

args.push_back("list");

if (vm.count("format")) {
args.push_back("--format");
args.push_back(vm["format"].as<at::Format>().value.c_str());
}
if (vm["pretty-format"].as<bool>()) {
args.push_back("--pretty-format");
}

return call_ggate_cmd(vm, args);
}

Expand All @@ -102,28 +135,13 @@ void get_map_arguments(po::options_description *positional,

int execute_map(const po::variables_map &vm)
{
size_t arg_index = 0;
std::string pool_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, &image_name,
&snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED,
utils::SPEC_VALIDATION_NONE);
if (r < 0) {
return r;
}

std::vector<const char*> args;

args.push_back("map");
std::string img;
img.append(pool_name);
img.append("/");
img.append(image_name);
if (!snap_name.empty()) {
img.append("@");
img.append(snap_name);
int r = get_image_or_snap_spec(vm, &img);
if (r < 0) {
return r;
}
args.push_back(img.c_str());

Expand All @@ -145,7 +163,12 @@ void get_unmap_arguments(po::options_description *positional,
po::options_description *options)
{
positional->add_options()
("device-spec", "specify ggate device");
("image-or-snap-or-device-spec",
"image, snapshot, or device specification\n"
"[<pool-name>/]<image-name>[@<snapshot-name>] or <device-path>");
at::add_pool_option(options, at::ARGUMENT_MODIFIER_NONE);
at::add_image_option(options, at::ARGUMENT_MODIFIER_NONE);
at::add_snap_option(options, at::ARGUMENT_MODIFIER_NONE);
}

int execute_unmap(const po::variables_map &vm)
Expand All @@ -155,15 +178,25 @@ int execute_unmap(const po::variables_map &vm)
device_name.clear();
}

std::string image_name;
if (device_name.empty()) {
std::cerr << "rbd: ggate unmap requires device path" << std::endl;
int r = get_image_or_snap_spec(vm, &image_name);
if (r < 0) {
return r;
}
}

if (device_name.empty() && image_name.empty()) {
std::cerr << "rbd: unmap requires either image name or device path"
<< std::endl;
return -EINVAL;
}

std::vector<const char*> args;

args.push_back("unmap");
args.push_back(device_name.c_str());
args.push_back(device_name.empty() ? image_name.c_str() :
device_name.c_str());

return call_ggate_cmd(vm, args);
}
Expand Down
19 changes: 9 additions & 10 deletions src/tools/rbd_ggate/Driver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,32 +29,31 @@ int Driver::kill(const std::string &devname) {
return r;
}

int Driver::list(std::list<std::string> &devs) {
int Driver::list(std::map<std::string, DevInfo> *devices) {
size_t size = 1024;
char **devs_ = nullptr;
ggate_drv_info *devs = nullptr;
int r;

while (size <= 1024 * 1024) {
devs_ = static_cast<char **>(
realloc(static_cast<void *>(devs_), size * sizeof(*devs_)));
r = ggate_drv_list(devs_, &size);
devs = static_cast<ggate_drv_info *>(
realloc(static_cast<void *>(devs), size * sizeof(*devs)));
r = ggate_drv_list(devs, &size);
if (r != -ERANGE) {
break;
}
size *= 2;
}
if (r < 0) {
goto free;
}

devs.clear();
devices->clear();
for (size_t i = 0; i < size; i++) {
devs.push_back(devs_[i]);
auto &dev = devs[i];
(*devices)[dev.id] = {dev.name, dev.info};
}

ggate_drv_list_free(devs_, size);
free:
free(devs_);
free(devs);

return r;
}
Expand Down
5 changes: 3 additions & 2 deletions src/tools/rbd_ggate/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#ifndef CEPH_RBD_GGATE_DRIVER_H
#define CEPH_RBD_GGATE_DRIVER_H

#include <list>
#include <map>
#include <string>

#include "ggate_drv.h"
Expand All @@ -16,9 +16,10 @@ struct Request;

class Driver {
public:
typedef std::pair<std::string, std::string> DevInfo;
static int load();
static int kill(const std::string &devname);
static int list(std::list<std::string> &devs);
static int list(std::map<std::string, DevInfo> *devices);

Driver(const std::string &devname, size_t sectorsize, size_t mediasize,
bool readonly, const std::string &info);
Expand Down
26 changes: 15 additions & 11 deletions src/tools/rbd_ggate/ggate_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,17 @@ int ggate_drv_send(ggate_drv_t drv_, ggate_drv_req_t req) {
return r;
}

int ggate_drv_list(char **devs, size_t *size) {
static const char * get_conf(struct ggeom *gp, const char *name) {
struct gconfig *conf;

LIST_FOREACH(conf, &gp->lg_config, lg_config) {
if (strcmp(conf->lg_name, name) == 0)
return (conf->lg_val);
}
return "";
}

int ggate_drv_list(struct ggate_drv_info *info, size_t *size) {
struct gmesh mesh;
struct gclass *class;
struct ggeom *gp;
Expand All @@ -355,8 +365,10 @@ int ggate_drv_list(char **devs, size_t *size) {
goto done;
}
LIST_FOREACH(gp, &class->lg_geom, lg_geom) {
*devs = strdup(gp->lg_name);
devs++;
strlcpy(info->id, get_conf(gp, "unit"), sizeof(info->id));
strlcpy(info->name, gp->lg_name, sizeof(info->name));
strlcpy(info->info, get_conf(gp, "info"), sizeof(info->info));
info++;
}
}
}
Expand All @@ -365,11 +377,3 @@ int ggate_drv_list(char **devs, size_t *size) {
geom_deletetree(&mesh);
return r;
}

void ggate_drv_list_free(char **devs, size_t size) {
size_t i;

for (i = 0; i < size; i++) {
free(devs[i]);
}
}
11 changes: 9 additions & 2 deletions src/tools/rbd_ggate/ggate_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
extern "C" {
#endif

#include <sys/param.h>

#include <stdbool.h>
#include <stdint.h>

Expand All @@ -25,6 +27,12 @@ enum {
GGATE_DRV_CMD_DISCARD = 4,
};

struct ggate_drv_info {
char id[16];
char name[NAME_MAX];
char info[2048]; /* G_GATE_INFOSIZE */
};

uint64_t ggate_drv_req_id(ggate_drv_req_t req);
int ggate_drv_req_cmd(ggate_drv_req_t req);
void *ggate_drv_req_buf(ggate_drv_req_t req);
Expand All @@ -47,8 +55,7 @@ int ggate_drv_send(ggate_drv_t drv, ggate_drv_req_t req);
int ggate_drv_resize(ggate_drv_t drv, size_t newsize);

int ggate_drv_kill(const char *devname);
int ggate_drv_list(char **devs, size_t *size);
void ggate_drv_list_free(char **devs, size_t size);
int ggate_drv_list(struct ggate_drv_info *info, size_t *size);

#ifdef __cplusplus
}
Expand Down