nbd: use pthread_create instead of fork
Using pthread_create is much cleaner, and avoids race conditions related to the forked process sharing memory with the primary process. Specifically this fixes a double spdk_event_call() of the shutdown event - one from each process. The primary process may have already recycled the shutdown event, and when the forked process calls it again, hilarity ensues. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I3e4b77b8b380a8fa0227b770758099bcee0ef35b Reviewed-on: https://review.gerrithub.io/388520 Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
1517ed376d
commit
dd01e9353d
@ -350,19 +350,20 @@ spdk_nbd_poll(struct spdk_nbd_disk *nbd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void *
|
||||||
nbd_start_kernel(struct spdk_nbd_disk *nbd)
|
nbd_start_kernel(void *arg)
|
||||||
{
|
{
|
||||||
|
struct spdk_nbd_disk *nbd = arg;
|
||||||
int rc;
|
int rc;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
close(nbd->spdk_sp_fd);
|
spdk_unaffinitize_thread();
|
||||||
|
|
||||||
rc = ioctl(nbd->dev_fd, NBD_SET_SOCK, nbd->kernel_sp_fd);
|
rc = ioctl(nbd->dev_fd, NBD_SET_SOCK, nbd->kernel_sp_fd);
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
spdk_strerror_r(errno, buf, sizeof(buf));
|
spdk_strerror_r(errno, buf, sizeof(buf));
|
||||||
SPDK_ERRLOG("ioctl(NBD_SET_SOCK) failed: %s\n", buf);
|
SPDK_ERRLOG("ioctl(NBD_SET_SOCK) failed: %s\n", buf);
|
||||||
exit(-1);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NBD_FLAG_SEND_TRIM
|
#ifdef NBD_FLAG_SEND_TRIM
|
||||||
@ -370,23 +371,22 @@ nbd_start_kernel(struct spdk_nbd_disk *nbd)
|
|||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
spdk_strerror_r(errno, buf, sizeof(buf));
|
spdk_strerror_r(errno, buf, sizeof(buf));
|
||||||
SPDK_ERRLOG("ioctl(NBD_SET_FLAGS) failed: %s\n", buf);
|
SPDK_ERRLOG("ioctl(NBD_SET_FLAGS) failed: %s\n", buf);
|
||||||
exit(-1);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This will block in the kernel until the client disconnects. */
|
/* This will block in the kernel until we close the spdk_sp_fd. */
|
||||||
ioctl(nbd->dev_fd, NBD_DO_IT);
|
ioctl(nbd->dev_fd, NBD_DO_IT);
|
||||||
|
|
||||||
ioctl(nbd->dev_fd, NBD_CLEAR_QUE);
|
ioctl(nbd->dev_fd, NBD_CLEAR_QUE);
|
||||||
ioctl(nbd->dev_fd, NBD_CLEAR_SOCK);
|
ioctl(nbd->dev_fd, NBD_CLEAR_SOCK);
|
||||||
|
pthread_exit(NULL);
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spdk_nbd_disk *
|
struct spdk_nbd_disk *
|
||||||
spdk_nbd_start(struct spdk_bdev *bdev, const char *nbd_path)
|
spdk_nbd_start(struct spdk_bdev *bdev, const char *nbd_path)
|
||||||
{
|
{
|
||||||
struct spdk_nbd_disk *nbd;
|
struct spdk_nbd_disk *nbd;
|
||||||
|
pthread_t tid;
|
||||||
int rc;
|
int rc;
|
||||||
int sp[2];
|
int sp[2];
|
||||||
char buf[64];
|
char buf[64];
|
||||||
@ -448,23 +448,13 @@ spdk_nbd_start(struct spdk_bdev *bdev, const char *nbd_path)
|
|||||||
|
|
||||||
printf("Enabling kernel access to bdev %s via %s\n", spdk_bdev_get_name(bdev), nbd_path);
|
printf("Enabling kernel access to bdev %s via %s\n", spdk_bdev_get_name(bdev), nbd_path);
|
||||||
|
|
||||||
rc = fork();
|
rc = pthread_create(&tid, NULL, &nbd_start_kernel, nbd);
|
||||||
|
if (rc != 0) {
|
||||||
switch (rc) {
|
spdk_strerror_r(rc, buf, sizeof(buf));
|
||||||
case 0:
|
SPDK_ERRLOG("could not create thread: %s\n", buf);
|
||||||
nbd_start_kernel(nbd);
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
spdk_strerror_r(errno, buf, sizeof(buf));
|
|
||||||
SPDK_ERRLOG("could not fork: %s\n", buf);
|
|
||||||
goto err;
|
goto err;
|
||||||
default:
|
|
||||||
close(nbd->dev_fd);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close(nbd->kernel_sp_fd);
|
|
||||||
|
|
||||||
fcntl(nbd->spdk_sp_fd, F_SETFL, O_NONBLOCK);
|
fcntl(nbd->spdk_sp_fd, F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
to_be32(&nbd->io.resp.magic, NBD_REPLY_MAGIC);
|
to_be32(&nbd->io.resp.magic, NBD_REPLY_MAGIC);
|
||||||
|
Loading…
Reference in New Issue
Block a user