Skip to content

Commit

Permalink
Add initial rpc support
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacKhor committed Aug 7, 2024
1 parent 7e12c27 commit 9de5a31
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 3 deletions.
6 changes: 6 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ executable(
dependencies: lsvd_deps + [dependency('_spdk')],
)

executable(
'lsvd_tgt',
lsvd_tgt,
dependencies: lsvd_deps + [dependency('_spdk')],
)

executable(
'imgtool',
['src/imgtool.cc'],
Expand Down
13 changes: 12 additions & 1 deletion src/bdev_lsvd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "request.h"
#include "smartiov.h"
#include "spdk/thread.h"
#include "src/backend.h"
#include "src/config.h"
#include "utils.h"

static int bdev_lsvd_init(void);
Expand Down Expand Up @@ -217,7 +219,16 @@ int bdev_lsvd_create(str img_name, rados_ioctx_t ioctx, lsvd_config cfg)
return 0;
}

int bdev_lsvd_delete(std::string img_name)
int bdev_lsvd_create(str pool_name, str image_name, str cfg_path)
{
auto be = connect_to_pool(pool_name);
auto cfg = lsvd_config::from_file(cfg_path);
PR_RET_IF(!cfg.has_value(), -1, "Failed to read config file");

return bdev_lsvd_create(image_name, be, cfg.value());
}

int bdev_lsvd_delete(str img_name)
{
auto p = std::promise<int>();
spdk_bdev_unregister_by_name(
Expand Down
1 change: 1 addition & 0 deletions src/bdev_lsvd.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
#include "config.h"

int bdev_lsvd_create(str img_name, rados_ioctx_t io_ctx, lsvd_config cfg);
int bdev_lsvd_create(str pool_name, str image_name, str cfg_path);
int bdev_lsvd_delete(str img_name);
99 changes: 99 additions & 0 deletions src/bdev_lsvd_rpc.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "spdk/bdev.h"
#include "spdk/json.h"
#include "spdk/jsonrpc.h"
#include "spdk/likely.h"
#include "spdk/log.h"
#include "spdk/nvme.h"
#include "spdk/rpc.h"
#include "spdk/util.h"

#include "bdev_lsvd.h"
#include "utils.h"

/**
* We only expose 2 RPC endpoints: create and delete. Unlike RBD, we will not
* have commands to manage ceph clusters; each image will create its own.
*/

struct rpc_create_lsvd {
char *image_name;
char *pool_name;
char *config;
};

static const struct spdk_json_object_decoder rpc_create_lsvd_decoders[] = {
{"image_name", offsetof(rpc_create_lsvd, image_name),
spdk_json_decode_string, false},
{"pool_name", offsetof(rpc_create_lsvd, pool_name), spdk_json_decode_string,
false},
{"config", offsetof(rpc_create_lsvd, config), spdk_json_decode_string,
true},
};

static void rpc_bdev_lsvd_create(spdk_jsonrpc_request *req_json,
const spdk_json_val *params)
{
spdk_json_write_ctx *w;
std::unique_ptr<rpc_create_lsvd, decltype([](auto p) {
free(p->image_name);
free(p->pool_name);
free(p->config);
})>
req(new rpc_create_lsvd());

auto rc = spdk_json_decode_object(params, rpc_create_lsvd_decoders,
SPDK_COUNTOF(rpc_create_lsvd_decoders),
req.get());
PR_GOTO_IF(rc != 0, fail, "spdk_json_decode_object failed\n");

rc = bdev_lsvd_create(req->pool_name, req->image_name, req->config);
PR_GOTO_IF(rc != 0, fail, "failed to create lsvd bdev\n");

w = spdk_jsonrpc_begin_result(req_json);
PR_GOTO_IF(w == nullptr, fail, "failed to create json result\n");
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(req_json, w);

fail:
spdk_jsonrpc_send_error_response(req_json, rc,
"failed to create lsvd bdev");
}

SPDK_RPC_REGISTER("bdev_lsvd_create", rpc_bdev_lsvd_create, SPDK_RPC_RUNTIME)

struct rpc_delete_lsvd {
char *image_name;
};

static const struct spdk_json_object_decoder rpc_delete_lsvd_decoders[] = {
{"image_name", offsetof(struct rpc_delete_lsvd, image_name),
spdk_json_decode_string, false},
};

static void rpc_bdev_lsvd_delete(struct spdk_jsonrpc_request *req_json,
const struct spdk_json_val *params)
{
spdk_json_write_ctx *w;
std::unique_ptr<rpc_delete_lsvd,
decltype([](auto p) { free(p->image_name); })>
req(new rpc_delete_lsvd());

int rc = spdk_json_decode_object(params, rpc_delete_lsvd_decoders,
SPDK_COUNTOF(rpc_delete_lsvd_decoders),
req.get());
PR_GOTO_IF(rc != 0, fail, "failed to decode json object\n");

rc = bdev_lsvd_delete(req->image_name);
PR_GOTO_IF(rc != 0, fail, "failed to destroy lsvd bdev");

w = spdk_jsonrpc_begin_result(req_json);
PR_GOTO_IF(w == nullptr, fail, "failed to create json result\n");
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(req_json, w);

fail:
spdk_jsonrpc_send_error_response(req_json, rc,
"failed to create lsvd bdev");
}

SPDK_RPC_REGISTER("bdev_lsvd_delete", rpc_bdev_lsvd_delete, SPDK_RPC_RUNTIME)
3 changes: 3 additions & 0 deletions src/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* LGPL-2.1-or-later
*/

#include "src/utils.h"
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
Expand Down Expand Up @@ -112,6 +113,8 @@ int lsvd_config::read()
return 0; // success
}

opt<lsvd_config> lsvd_config::from_file(str path) { UNIMPLEMENTED(); }

std::string lsvd_config::cache_filename(uuid_t &uuid, const char *name,
cfg_cache_type type)
{
Expand Down
5 changes: 3 additions & 2 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ class lsvd_config
lsvd_config() {}
~lsvd_config() {}
int read();
std::string cache_filename(uuid_t &uuid, const char *name,
cfg_cache_type type);
str cache_filename(uuid_t &uuid, const char *name, cfg_cache_type type);

inline fspath wlog_path(str imgname)
{
auto filename = imgname + ".wlog";
return fspath(wcache_dir) / filename;
}

static opt<lsvd_config> from_file(str path);
};
29 changes: 29 additions & 0 deletions src/lsvd_tgt.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "spdk/event.h"

#include "utils.h"

static void lsvd_tgt_usage() {}
static int lsvd_tgt_parse_arg(int ch, char *arg) { return 0; }

static void lsvd_tgt_started(void *arg1)
{
log_info("LSVD SPDK nvmf target started");
}

int main(int argc, char **argv)
{
int rc;
struct spdk_app_opts opts = {};

spdk_app_opts_init(&opts, sizeof(opts));
opts.name = "lsvd_tgt";
if ((rc = spdk_app_parse_args(argc, argv, &opts, "", NULL,
lsvd_tgt_parse_arg, lsvd_tgt_usage)) !=
SPDK_APP_PARSE_ARGS_SUCCESS) {
exit(rc);
}

rc = spdk_app_start(&opts, lsvd_tgt_started, NULL);
spdk_app_fini();
return rc;
}
4 changes: 4 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ lsvd_deps = [
spdk_fe = lsvd_src + files(
'bdev_lsvd.cc',
'spdk_frontend.cc',
)

lsvd_tgt = lsvd_src + files(
'lsvd_tgt.cc',
)
8 changes: 8 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ using fspath = std::filesystem::path;
} \
} while (0)

#define PR_GOTO_IF(cond, lbl, MSG, ...) \
do { \
if (cond) { \
log_error(MSG, ##__VA_ARGS__); \
goto lbl; \
} \
} while (0)

/**
* If `cond` is true, print an error message to stdout with MSG, then return
* `ret`
Expand Down

0 comments on commit 9de5a31

Please sign in to comment.