Whamcloud - gitweb
LU-464 obdfilter-survey test 2a ASSERT(imp->imp_sec == NULL)
authorLai Siyao <laisiyao@whamcloud.com>
Wed, 13 Jul 2011 08:00:40 +0000 (16:00 +0800)
committerOleg Drokin <green@whamcloud.com>
Fri, 15 Jul 2011 14:32:27 +0000 (07:32 -0700)
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>
lustre/osc/osc_request.c

index 7f57030..7cdf82f 100644 (file)
@@ -4490,6 +4490,16 @@ static int osc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
                 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) {