summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
e99739d)
There is a race in echo client:
1. `lctl --device $echo_client_dev detach`
-> class_detach() puts last refcount of export
-> obd_zombie_add_export() adds this export in zombie list, and
wake up zombie thread.
2. zombie thread culls this export:
class_destroy_export() put last refcount of echo_client_dev
-> obd_cleanup()
-> echo_device_free()
-> echo_client_cleanup()
-> osc_disconnect()
-> client_disconnect_export() will clear cli->cl_import
3. `lctl --device $osc_dev cleanup`
-> osc_precleanup() find scli->cl_import is not NULL (this means
import is never connected, but it's not true here)
-> class_destroy_import()
-> class_import_put()
-> LASSERT(imp->imp_sec == NULL) fails
It's expected that step 2 is done before step 3, but this can't be
guaranteed currently. To ensure this, osc_precleanup() calls
obd_zombie_barrier() to ensure step 2 is finished.
Change-Id: I2d044c3ac45a72d305a369a1f31c315f36a7ce02
Signed-off-by: Lai Siyao <laisiyao@whamcloud.com>
Reviewed-on: http://review.whamcloud.com/1093
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Mikhail Pershin <tappro@whamcloud.com>
Reviewed-by: Jinshan Xiong <jay@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
break;
}
case OBD_CLEANUP_EXPORTS: {
break;
}
case OBD_CLEANUP_EXPORTS: {
+ /* LU-464
+ * for echo client, export may be on zombie list, wait for
+ * zombie thread to cull it, because cli.cl_import will be
+ * cleared in client_disconnect_export():
+ * class_export_destroy() -> obd_cleanup() ->
+ * echo_device_free() -> echo_client_cleanup() ->
+ * obd_disconnect() -> osc_disconnect() ->
+ * client_disconnect_export()
+ */
+ obd_zombie_barrier();
/* If we set up but never connected, the
client import will not have been cleaned. */
if (obd->u.cli.cl_import) {
/* If we set up but never connected, the
client import will not have been cleaned. */
if (obd->u.cli.cl_import) {