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;
|
||||
}
|
||||
|
||||
static void
|
||||
nbd_start_kernel(struct spdk_nbd_disk *nbd)
|
||||
static void *
|
||||
nbd_start_kernel(void *arg)
|
||||
{
|
||||
struct spdk_nbd_disk *nbd = arg;
|
||||
int rc;
|
||||
char buf[64];
|
||||
|
||||
close(nbd->spdk_sp_fd);
|
||||
spdk_unaffinitize_thread();
|
||||
|
||||
rc = ioctl(nbd->dev_fd, NBD_SET_SOCK, nbd->kernel_sp_fd);
|
||||
if (rc == -1) {
|
||||
spdk_strerror_r(errno, buf, sizeof(buf));
|
||||
SPDK_ERRLOG("ioctl(NBD_SET_SOCK) failed: %s\n", buf);
|
||||
exit(-1);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
#ifdef NBD_FLAG_SEND_TRIM
|
||||
@ -370,23 +371,22 @@ nbd_start_kernel(struct spdk_nbd_disk *nbd)
|
||||
if (rc == -1) {
|
||||
spdk_strerror_r(errno, buf, sizeof(buf));
|
||||
SPDK_ERRLOG("ioctl(NBD_SET_FLAGS) failed: %s\n", buf);
|
||||
exit(-1);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
#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_CLEAR_QUE);
|
||||
ioctl(nbd->dev_fd, NBD_CLEAR_SOCK);
|
||||
|
||||
exit(0);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
struct spdk_nbd_disk *
|
||||
spdk_nbd_start(struct spdk_bdev *bdev, const char *nbd_path)
|
||||
{
|
||||
struct spdk_nbd_disk *nbd;
|
||||
pthread_t tid;
|
||||
int rc;
|
||||
int sp[2];
|
||||
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);
|
||||
|
||||
rc = fork();
|
||||
|
||||
switch (rc) {
|
||||
case 0:
|
||||
nbd_start_kernel(nbd);
|
||||
break;
|
||||
case -1:
|
||||
spdk_strerror_r(errno, buf, sizeof(buf));
|
||||
SPDK_ERRLOG("could not fork: %s\n", buf);
|
||||
rc = pthread_create(&tid, NULL, &nbd_start_kernel, nbd);
|
||||
if (rc != 0) {
|
||||
spdk_strerror_r(rc, buf, sizeof(buf));
|
||||
SPDK_ERRLOG("could not create thread: %s\n", buf);
|
||||
goto err;
|
||||
default:
|
||||
close(nbd->dev_fd);
|
||||
break;
|
||||
}
|
||||
|
||||
close(nbd->kernel_sp_fd);
|
||||
|
||||
fcntl(nbd->spdk_sp_fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
to_be32(&nbd->io.resp.magic, NBD_REPLY_MAGIC);
|
||||
|
Loading…
Reference in New Issue
Block a user