nbd: Make spdk_nbd_start asynchronous
Add a callback to spdk_nbd_start so that it can complete asynchronously. As of this patch, it always calls the callback immediately. Change-Id: I6156fb203145362afa5e4102183b6cf143051c0c Signed-off-by: Ben Walker <benjamin.walker@intel.com> Reviewed-on: https://review.gerrithub.io/433937 Tested-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
027a8e4b54
commit
2fe6d1d5d4
@ -59,16 +59,24 @@ int spdk_nbd_init(void);
|
||||
*/
|
||||
void spdk_nbd_fini(void);
|
||||
|
||||
/**
|
||||
* Called when an NBD device has been started.
|
||||
*/
|
||||
typedef void (*spdk_nbd_start_cb)(void *cb_arg, struct spdk_nbd_disk *nbd,
|
||||
int rc);
|
||||
|
||||
/**
|
||||
* Start a network block device backed by the bdev.
|
||||
*
|
||||
* \param bdev_name Name of bdev exposed as a network block device.
|
||||
* \param nbd_path Path to the registered network block device.
|
||||
* \param cb_fn Called when the device has been started.
|
||||
* \param cb_arg Passed to cb_fn.
|
||||
*
|
||||
* \return a pointer to the configuration of the registered network block device
|
||||
* on success, or NULL on failure.
|
||||
* \return A negated error number is passed to cb_fn on failure.
|
||||
*/
|
||||
struct spdk_nbd_disk *spdk_nbd_start(const char *bdev_name, const char *nbd_path);
|
||||
void spdk_nbd_start(const char *bdev_name, const char *nbd_path,
|
||||
spdk_nbd_start_cb cb_fn, void *cb_arg);
|
||||
|
||||
/**
|
||||
* Stop the running network block device safely.
|
||||
|
@ -837,10 +837,11 @@ spdk_nbd_bdev_hot_remove(void *remove_ctx)
|
||||
spdk_nbd_stop(nbd);
|
||||
}
|
||||
|
||||
struct spdk_nbd_disk *
|
||||
spdk_nbd_start(const char *bdev_name, const char *nbd_path)
|
||||
void
|
||||
spdk_nbd_start(const char *bdev_name, const char *nbd_path,
|
||||
spdk_nbd_start_cb cb_fn, void *cb_arg)
|
||||
{
|
||||
struct spdk_nbd_disk *nbd;
|
||||
struct spdk_nbd_disk *nbd = NULL;
|
||||
struct spdk_bdev *bdev;
|
||||
pthread_t tid;
|
||||
int rc;
|
||||
@ -850,12 +851,14 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path)
|
||||
bdev = spdk_bdev_get_by_name(bdev_name);
|
||||
if (bdev == NULL) {
|
||||
SPDK_ERRLOG("no bdev %s exists\n", bdev_name);
|
||||
return NULL;
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
nbd = calloc(1, sizeof(*nbd));
|
||||
if (nbd == NULL) {
|
||||
return NULL;
|
||||
rc = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
nbd->dev_fd = -1;
|
||||
@ -884,6 +887,7 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path)
|
||||
nbd->nbd_path = strdup(nbd_path);
|
||||
if (!nbd->nbd_path) {
|
||||
SPDK_ERRLOG("strdup allocation failure\n");
|
||||
rc = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -899,24 +903,28 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path)
|
||||
nbd->dev_fd = open(nbd_path, O_RDWR);
|
||||
if (nbd->dev_fd == -1) {
|
||||
SPDK_ERRLOG("open(\"%s\") failed: %s\n", nbd_path, spdk_strerror(errno));
|
||||
rc = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = ioctl(nbd->dev_fd, NBD_SET_BLKSIZE, spdk_bdev_get_block_size(bdev));
|
||||
if (rc == -1) {
|
||||
SPDK_ERRLOG("ioctl(NBD_SET_BLKSIZE) failed: %s\n", spdk_strerror(errno));
|
||||
rc = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = ioctl(nbd->dev_fd, NBD_SET_SIZE_BLOCKS, spdk_bdev_get_num_blocks(bdev));
|
||||
if (rc == -1) {
|
||||
SPDK_ERRLOG("ioctl(NBD_SET_SIZE_BLOCKS) failed: %s\n", spdk_strerror(errno));
|
||||
rc = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = ioctl(nbd->dev_fd, NBD_CLEAR_SOCK);
|
||||
if (rc == -1) {
|
||||
SPDK_ERRLOG("ioctl(NBD_CLEAR_SOCK) failed: %s\n", spdk_strerror(errno));
|
||||
rc = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -926,6 +934,7 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path)
|
||||
rc = ioctl(nbd->dev_fd, NBD_SET_SOCK, nbd->kernel_sp_fd);
|
||||
if (rc == -1) {
|
||||
SPDK_ERRLOG("ioctl(NBD_SET_SOCK) failed: %s\n", spdk_strerror(errno));
|
||||
rc = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -933,6 +942,7 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path)
|
||||
rc = ioctl(nbd->dev_fd, NBD_SET_FLAGS, NBD_FLAG_SEND_TRIM);
|
||||
if (rc == -1) {
|
||||
SPDK_ERRLOG("ioctl(NBD_SET_FLAGS) failed: %s\n", spdk_strerror(errno));
|
||||
rc = -errno;
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
@ -953,17 +963,26 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path)
|
||||
if (fcntl(nbd->spdk_sp_fd, F_SETFL, flag | O_NONBLOCK) < 0) {
|
||||
SPDK_ERRLOG("fcntl can't set nonblocking mode for socket, fd: %d (%s)\n",
|
||||
nbd->spdk_sp_fd, spdk_strerror(errno));
|
||||
rc = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
nbd->nbd_poller = spdk_poller_register(spdk_nbd_poll, nbd, 0);
|
||||
|
||||
return nbd;
|
||||
if (cb_fn) {
|
||||
cb_fn(cb_arg, nbd, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
spdk_nbd_stop(nbd);
|
||||
if (nbd) {
|
||||
spdk_nbd_stop(nbd);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
if (cb_fn) {
|
||||
cb_fn(cb_arg, NULL, rc);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -58,12 +58,31 @@ static const struct spdk_json_object_decoder rpc_start_nbd_disk_decoders[] = {
|
||||
{"nbd_device", offsetof(struct rpc_start_nbd_disk, nbd_device), spdk_json_decode_string},
|
||||
};
|
||||
|
||||
static void
|
||||
spdk_rpc_start_nbd_done(void *cb_arg, struct spdk_nbd_disk *nbd, int rc)
|
||||
{
|
||||
struct spdk_jsonrpc_request *request = cb_arg;
|
||||
struct spdk_json_write_ctx *w;
|
||||
|
||||
if (rc) {
|
||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
|
||||
return;
|
||||
}
|
||||
|
||||
w = spdk_jsonrpc_begin_result(request);
|
||||
if (w == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
spdk_json_write_string(w, spdk_nbd_get_path(nbd));
|
||||
spdk_jsonrpc_end_result(request, w);
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_rpc_start_nbd_disk(struct spdk_jsonrpc_request *request,
|
||||
const struct spdk_json_val *params)
|
||||
{
|
||||
struct rpc_start_nbd_disk req = {};
|
||||
struct spdk_json_write_ctx *w;
|
||||
struct spdk_nbd_disk *nbd;
|
||||
|
||||
if (spdk_json_decode_object(params, rpc_start_nbd_disk_decoders,
|
||||
@ -83,19 +102,9 @@ spdk_rpc_start_nbd_disk(struct spdk_jsonrpc_request *request,
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
nbd = spdk_nbd_start(req.bdev_name, req.nbd_device);
|
||||
if (!nbd) {
|
||||
goto invalid;
|
||||
}
|
||||
spdk_nbd_start(req.bdev_name, req.nbd_device,
|
||||
spdk_rpc_start_nbd_done, request);
|
||||
|
||||
w = spdk_jsonrpc_begin_result(request);
|
||||
if (w == NULL) {
|
||||
free_rpc_start_nbd_disk(&req);
|
||||
return;
|
||||
}
|
||||
|
||||
spdk_json_write_string(w, req.nbd_device);
|
||||
spdk_jsonrpc_end_result(request, w);
|
||||
free_rpc_start_nbd_disk(&req);
|
||||
return;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user