Skip to content

Commit

Permalink
Fix deletion deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacKhor committed Aug 9, 2024
1 parent 37f9b72 commit 6f504b3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 29 deletions.
24 changes: 14 additions & 10 deletions src/bdev_lsvd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -228,19 +228,23 @@ int bdev_lsvd_create(str pool_name, str image_name, str user_cfg)
return bdev_lsvd_create(image_name, be, cfg.value());
}

int bdev_lsvd_delete(str img_name)
void bdev_lsvd_delete(str img_name, std::function<void(int)> cb)
{
// TODO this currently deadlocks because of spdk's threading model, need to
// make it async
log_info("Deleting image '{}'", img_name);
auto p = std::promise<int>();
spdk_bdev_unregister_by_name(
auto rc = spdk_bdev_unregister_by_name(
img_name.c_str(), &lsvd_if,
// some of the ugliest lifetime management code you'll ever see, but
// it should work
[](void *arg, int rc) {
log_info("Image deletion complete, rc = {}", rc);
auto p = (std::promise<int> *)arg;
p->set_value(rc);
log_info("Image deletion done, rc = {}", rc);
auto cb = (std::function<void(int)> *)arg;
(*cb)(rc);
delete cb;
},
&p);
return p.get_future().get();
new std::function<void(int)>(cb));

if (rc != 0) {
log_error("Failed to delete image '{}': {}", img_name, rc);
cb(rc);
}
}
3 changes: 2 additions & 1 deletion src/bdev_lsvd.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#pragma once

#include <rados/librados.h>
#include <functional>

#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);
void bdev_lsvd_delete(str img_name, std::function<void(int)> cb);
43 changes: 25 additions & 18 deletions src/bdev_lsvd_rpc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ struct rpc_create_lsvd {
};

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},
{"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,
Expand Down Expand Up @@ -64,33 +67,37 @@ struct rpc_delete_lsvd {
};

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},
{"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");

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");
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");
if (rc != 0) {
spdk_jsonrpc_send_error_response(req_json, rc,
"Failed to parse rpc json");
return;
}

bdev_lsvd_delete(req->image_name, [=](int rc) {
if (rc == 0) {
auto w = spdk_jsonrpc_begin_result(req_json);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(req_json, w);
} else {
log_error("Failed to destroy lsvd bdev, rc = {}", rc);
spdk_jsonrpc_send_error_response(req_json, rc,
"Failed to destroy lsvd bdev");
}
});
}

SPDK_RPC_REGISTER("bdev_lsvd_delete", rpc_bdev_lsvd_delete, SPDK_RPC_RUNTIME)

0 comments on commit 6f504b3

Please sign in to comment.