nbd: allow exporting more than one NBD at once
Change-Id: Ib6245e981d550e951a518176730a0e8d88378207 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-on: https://review.gerrithub.io/372341 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
b4b59e6aa7
commit
610374cd49
@ -35,16 +35,17 @@
|
||||
#define SPDK_NBD_H_
|
||||
|
||||
struct spdk_bdev;
|
||||
struct spdk_nbd_disk;
|
||||
|
||||
int spdk_nbd_start(struct spdk_bdev *bdev, const char *nbd_path);
|
||||
struct spdk_nbd_disk *spdk_nbd_start(struct spdk_bdev *bdev, const char *nbd_path);
|
||||
|
||||
/**
|
||||
* Poll an NBD instance.
|
||||
*
|
||||
* \return 0 on success or negated errno values on error (e.g. connection closed).
|
||||
*/
|
||||
int spdk_nbd_poll(void);
|
||||
int spdk_nbd_poll(struct spdk_nbd_disk *nbd);
|
||||
|
||||
void spdk_nbd_stop(void);
|
||||
void spdk_nbd_stop(struct spdk_nbd_disk *nbd);
|
||||
|
||||
#endif
|
||||
|
@ -65,7 +65,7 @@ struct nbd_io {
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct nbd_disk {
|
||||
struct spdk_nbd_disk {
|
||||
struct spdk_bdev *bdev;
|
||||
struct spdk_bdev_desc *bdev_desc;
|
||||
struct spdk_io_channel *ch;
|
||||
@ -74,8 +74,6 @@ struct nbd_disk {
|
||||
uint32_t buf_align;
|
||||
};
|
||||
|
||||
struct nbd_disk g_nbd_disk = {};
|
||||
|
||||
static bool
|
||||
is_read(enum spdk_bdev_io_type io_type)
|
||||
{
|
||||
@ -99,11 +97,25 @@ is_write(enum spdk_bdev_io_type io_type)
|
||||
}
|
||||
|
||||
void
|
||||
spdk_nbd_stop(void)
|
||||
spdk_nbd_stop(struct spdk_nbd_disk *nbd)
|
||||
{
|
||||
spdk_put_io_channel(g_nbd_disk.ch);
|
||||
spdk_bdev_close(g_nbd_disk.bdev_desc);
|
||||
close(g_nbd_disk.fd);
|
||||
if (nbd == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nbd->ch) {
|
||||
spdk_put_io_channel(nbd->ch);
|
||||
}
|
||||
|
||||
if (nbd->bdev_desc) {
|
||||
spdk_bdev_close(nbd->bdev_desc);
|
||||
}
|
||||
|
||||
if (nbd->fd >= 0) {
|
||||
close(nbd->fd);
|
||||
}
|
||||
|
||||
free(nbd);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
@ -192,7 +204,7 @@ nbd_submit_bdev_io(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
|
||||
}
|
||||
|
||||
static int
|
||||
process_request(struct nbd_disk *nbd)
|
||||
process_request(struct spdk_nbd_disk *nbd)
|
||||
{
|
||||
struct nbd_io *io = &nbd->io;
|
||||
|
||||
@ -239,9 +251,8 @@ process_request(struct nbd_disk *nbd)
|
||||
}
|
||||
|
||||
int
|
||||
spdk_nbd_poll(void)
|
||||
spdk_nbd_poll(struct spdk_nbd_disk *nbd)
|
||||
{
|
||||
struct nbd_disk *nbd = &g_nbd_disk;
|
||||
struct nbd_io *io = &nbd->io;
|
||||
int fd = nbd->fd;
|
||||
int64_t ret;
|
||||
@ -338,50 +349,57 @@ nbd_start_kernel(int nbd_fd, int *sp)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
struct spdk_nbd_disk *
|
||||
spdk_nbd_start(struct spdk_bdev *bdev, const char *nbd_path)
|
||||
{
|
||||
struct spdk_nbd_disk *nbd;
|
||||
int rc;
|
||||
int sp[2], nbd_fd;
|
||||
int sp[2] = { -1, -1 }, nbd_fd = -1;
|
||||
|
||||
rc = spdk_bdev_open(bdev, true, NULL, NULL, &g_nbd_disk.bdev_desc);
|
||||
nbd = calloc(1, sizeof(*nbd));
|
||||
if (nbd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
nbd->fd = -1;
|
||||
|
||||
rc = spdk_bdev_open(bdev, true, NULL, NULL, &nbd->bdev_desc);
|
||||
if (rc != 0) {
|
||||
SPDK_ERRLOG("could not open bdev %s, error=%d\n", spdk_bdev_get_name(bdev), rc);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
g_nbd_disk.bdev = bdev;
|
||||
g_nbd_disk.ch = spdk_bdev_get_io_channel(g_nbd_disk.bdev_desc);
|
||||
g_nbd_disk.buf_align = spdk_max(spdk_bdev_get_buf_align(bdev), 64);
|
||||
nbd->bdev = bdev;
|
||||
nbd->ch = spdk_bdev_get_io_channel(nbd->bdev_desc);
|
||||
nbd->buf_align = spdk_max(spdk_bdev_get_buf_align(bdev), 64);
|
||||
|
||||
rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sp);
|
||||
if (rc != 0) {
|
||||
SPDK_ERRLOG("socketpair failed\n");
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
nbd_fd = open(nbd_path, O_RDWR);
|
||||
if (nbd_fd == -1) {
|
||||
SPDK_ERRLOG("open(\"%s\") failed: %s\n", nbd_path, strerror(errno));
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = ioctl(nbd_fd, NBD_SET_BLKSIZE, spdk_bdev_get_block_size(bdev));
|
||||
if (rc == -1) {
|
||||
SPDK_ERRLOG("ioctl(NBD_SET_BLKSIZE) failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = ioctl(nbd_fd, NBD_SET_SIZE_BLOCKS, spdk_bdev_get_num_blocks(bdev));
|
||||
if (rc == -1) {
|
||||
SPDK_ERRLOG("ioctl(NBD_SET_SIZE_BLOCKS) failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = ioctl(nbd_fd, NBD_CLEAR_SOCK);
|
||||
if (rc == -1) {
|
||||
SPDK_ERRLOG("ioctl(NBD_CLEAR_SOCK) failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
printf("Enabling kernel access to bdev %s via %s\n", spdk_bdev_get_name(bdev), nbd_path);
|
||||
@ -394,18 +412,36 @@ spdk_nbd_start(struct spdk_bdev *bdev, const char *nbd_path)
|
||||
break;
|
||||
case -1:
|
||||
SPDK_ERRLOG("could not fork: %s\n", strerror(errno));
|
||||
return -1;
|
||||
goto err;
|
||||
default:
|
||||
close(nbd_fd);
|
||||
break;
|
||||
}
|
||||
|
||||
close(sp[1]);
|
||||
|
||||
g_nbd_disk.fd = sp[0];
|
||||
fcntl(g_nbd_disk.fd, F_SETFL, O_NONBLOCK);
|
||||
nbd->fd = sp[0];
|
||||
fcntl(nbd->fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
to_be32(&g_nbd_disk.io.resp.magic, NBD_REPLY_MAGIC);
|
||||
g_nbd_disk.io.req_in_progress = true;
|
||||
to_be32(&nbd->io.resp.magic, NBD_REPLY_MAGIC);
|
||||
nbd->io.req_in_progress = true;
|
||||
|
||||
return 0;
|
||||
return nbd;
|
||||
|
||||
err:
|
||||
if (sp[0] >= 0) {
|
||||
close(sp[0]);
|
||||
}
|
||||
|
||||
if (sp[1] >= 0) {
|
||||
close(sp[1]);
|
||||
}
|
||||
|
||||
if (nbd_fd >= 0) {
|
||||
close(nbd_fd);
|
||||
}
|
||||
|
||||
spdk_nbd_stop(nbd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "spdk/util.h"
|
||||
|
||||
static struct spdk_poller *g_nbd_poller;
|
||||
static struct spdk_nbd_disk *g_nbd_disk;
|
||||
static char *g_bdev_name;
|
||||
static char *g_nbd_name = "/dev/nbd0";
|
||||
|
||||
@ -52,7 +53,7 @@ static void
|
||||
nbd_shutdown(void)
|
||||
{
|
||||
spdk_poller_unregister(&g_nbd_poller, NULL);
|
||||
spdk_nbd_stop();
|
||||
spdk_nbd_stop(g_nbd_disk);
|
||||
spdk_app_stop(0);
|
||||
}
|
||||
|
||||
@ -61,7 +62,7 @@ nbd_poll(void *arg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = spdk_nbd_poll();
|
||||
rc = spdk_nbd_poll(g_nbd_disk);
|
||||
if (rc < 0) {
|
||||
SPDK_NOTICELOG("spdk_nbd_poll() returned %d; shutting down", rc);
|
||||
nbd_shutdown();
|
||||
@ -72,7 +73,6 @@ static void
|
||||
nbd_start(void *arg1, void *arg2)
|
||||
{
|
||||
struct spdk_bdev *bdev;
|
||||
int rc;
|
||||
|
||||
bdev = spdk_bdev_get_by_name(g_bdev_name);
|
||||
if (bdev == NULL) {
|
||||
@ -81,8 +81,8 @@ nbd_start(void *arg1, void *arg2)
|
||||
return;
|
||||
}
|
||||
|
||||
rc = spdk_nbd_start(bdev, g_nbd_name);
|
||||
if (rc != 0) {
|
||||
g_nbd_disk = spdk_nbd_start(bdev, g_nbd_name);
|
||||
if (g_nbd_disk == NULL) {
|
||||
spdk_app_stop(-1);
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user