lib/vhost: quit vhost subsystem while VM is connected
If we kill the vhost process while VM is connected, the `g_fini_cb`
will not be called due to active session is in the vhost-user device,
but we're sure that this VM is stopped for this case, because
`vhost_driver_unregister` is called in the shutdown thread, so here
we reuse `g_vhost_user_started` flag for this case and free the sessions,
the following call to `vhost_driver_unregister` can also handle this
case, because the Unix Domain socket is already unregistered.
Fixes commit 327d1c98
("vhost: defer vhost_dev_unregister until scsi tgts removed")
Change-Id: I4f368ac8c304dd9525d15abdce8fd5b2ed79b96e
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15623
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
63dab84449
commit
e753aa807f
@ -1776,6 +1776,8 @@ vhost_dev_thread_exit(void *arg1)
|
|||||||
spdk_thread_exit(spdk_get_thread());
|
spdk_thread_exit(spdk_get_thread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool g_vhost_user_started = false;
|
||||||
|
|
||||||
int
|
int
|
||||||
vhost_user_dev_register(struct spdk_vhost_dev *vdev, const char *name, struct spdk_cpuset *cpumask,
|
vhost_user_dev_register(struct spdk_vhost_dev *vdev, const char *name, struct spdk_cpuset *cpumask,
|
||||||
const struct spdk_vhost_user_dev_backend *user_backend)
|
const struct spdk_vhost_user_dev_backend *user_backend)
|
||||||
@ -1834,6 +1836,7 @@ int
|
|||||||
vhost_user_dev_unregister(struct spdk_vhost_dev *vdev)
|
vhost_user_dev_unregister(struct spdk_vhost_dev *vdev)
|
||||||
{
|
{
|
||||||
struct spdk_vhost_user_dev *user_dev = to_user_dev(vdev);
|
struct spdk_vhost_user_dev *user_dev = to_user_dev(vdev);
|
||||||
|
struct spdk_vhost_session *vsession;
|
||||||
|
|
||||||
pthread_mutex_lock(&user_dev->lock);
|
pthread_mutex_lock(&user_dev->lock);
|
||||||
if (user_dev->pending_async_op_num) {
|
if (user_dev->pending_async_op_num) {
|
||||||
@ -1841,11 +1844,29 @@ vhost_user_dev_unregister(struct spdk_vhost_dev *vdev)
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TAILQ_EMPTY(&user_dev->vsessions)) {
|
/* This is the case that uses RPC call `vhost_delete_controller` while VM is connected */
|
||||||
|
if (!TAILQ_EMPTY(&user_dev->vsessions) && g_vhost_user_started) {
|
||||||
SPDK_ERRLOG("Controller %s has still valid connection.\n", vdev->name);
|
SPDK_ERRLOG("Controller %s has still valid connection.\n", vdev->name);
|
||||||
pthread_mutex_unlock(&user_dev->lock);
|
pthread_mutex_unlock(&user_dev->lock);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is the case that quits the subsystem while VM is connected, the VM
|
||||||
|
* should be stopped by the shutdown thread.
|
||||||
|
*/
|
||||||
|
if (!g_vhost_user_started) {
|
||||||
|
TAILQ_FOREACH(vsession, &user_dev->vsessions, tailq) {
|
||||||
|
assert(vsession->started == false);
|
||||||
|
TAILQ_REMOVE(&user_dev->vsessions, vsession, tailq);
|
||||||
|
if (vsession->mem) {
|
||||||
|
vhost_session_mem_unregister(vsession->mem);
|
||||||
|
free(vsession->mem);
|
||||||
|
}
|
||||||
|
free(vsession->name);
|
||||||
|
free(vsession);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
user_dev->registered = false;
|
user_dev->registered = false;
|
||||||
pthread_mutex_unlock(&user_dev->lock);
|
pthread_mutex_unlock(&user_dev->lock);
|
||||||
|
|
||||||
@ -1863,8 +1884,6 @@ vhost_user_dev_unregister(struct spdk_vhost_dev *vdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool g_vhost_user_started = false;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
vhost_user_init(void)
|
vhost_user_init(void)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user