diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index 749966abe3465e865226af6a88fb0fb08f204689..af97f6a7b69316990e7959eeb2fd5d8072894246 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -24,6 +24,13 @@ tbd Sun Microsystems, Inc.
 	  	'tunefs.lustre --param="mdt.quota_type=ug1" $MDTDEV'.
 	  For more information, please refer to bugzilla 13904.
 
+Severity   : minor
+Bugzilla   : 15716
+Description: timeout with invalidate import.
+Details    : ptlrpcd_check call obd_zombie_impexp_cull and wait request which should be
+             handled by ptlrpcd. This produce long age waiting and -ETIMEOUT
+             ptlrpc_invalidate_import and as result LASSERT.
+
 Severity   : normal
 Frequency  : only with broken builds/installations
 Bugzilla   : 15779
diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h
index 75a77cd333d271e23c2c68ecd229a526c456dfde..dcb5ba12eb65b25afe7344be7927b39c311328f9 100644
--- a/lustre/include/linux/obd_class.h
+++ b/lustre/include/linux/obd_class.h
@@ -38,10 +38,6 @@
 #include <linux/timer.h>
 #endif
 
-void obd_zombie_impexp_init(void);
-void obd_zombie_impexp_cull(void);
-extern void (*obd_zombie_impexp_notify)(void);
-
 /* obdo.c */
 #ifdef __KERNEL__
 void obdo_from_iattr(struct obdo *oa, struct iattr *attr, unsigned ia_valid);
diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h
index 01dad5a1267e09156ea114b6466acae2aed86335..a6d1483fce3ce8abfd0005152e62588a6f8a5232 100644
--- a/lustre/include/obd_class.h
+++ b/lustre/include/obd_class.h
@@ -84,6 +84,10 @@ char *obd_export_nid2str(struct obd_export *exp);
 int obd_export_evict_by_nid(struct obd_device *obd, char *nid);
 int obd_export_evict_by_uuid(struct obd_device *obd, char *uuid);
 
+int obd_zombie_impexp_init(void);
+void obd_zombie_impexp_stop(void);
+void obd_zombie_impexp_cull(void);
+
 /* obd_config.c */
 int class_process_config(struct lustre_cfg *lcfg);
 int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, 
diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c
index f377629045709788118bfbe122a3500ed7ffe064..3495f3a5e15ca54f775ceee7d4d90120ea25297e 100644
--- a/lustre/mds/mds_lov.c
+++ b/lustre/mds/mds_lov.c
@@ -140,7 +140,7 @@ void mds_lov_destroy_objids(struct obd_device *obd)
         }
 
         if (mds->mds_lov_objid_filp) {
-                rc = filp_close((struct file *)mds->mds_lov_objid_filp, 0);
+                rc = filp_close((struct file *)mds->mds_lov_objid_filp, NULL);
                 mds->mds_lov_objid_filp = NULL;
                 if (rc)
                         CERROR("%s file won't close, rc=%d\n", LOV_OBJID, rc);
@@ -235,7 +235,7 @@ out:
 int mds_lov_write_objids(struct obd_device *obd)
 {
         struct mds_obd *mds = &obd->u.mds;
-        int i, rc = 0;
+        int i = 0, rc = 0;
         ENTRY;
 
         if (cfs_bitmap_check_empty(mds->mds_lov_page_dirty))
@@ -254,6 +254,7 @@ int mds_lov_write_objids(struct obd_device *obd)
                 if (i == mds->mds_lov_objid_lastpage)
                         size = (mds->mds_lov_objid_lastidx + 1) * sizeof(obd_id);
 
+		CDEBUG(D_INFO,"write %lld - %ld\n", off, size);
                 rc = fsfilt_write_record(obd, mds->mds_lov_objid_filp, data,
                                          size, &off, 0);
                 if (rc < 0)
diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c
index c97ca561ad852536981de691102a1503f55bb74e..ef4cc0ecdb6658c44eac91ebf7e55b253c43b565 100644
--- a/lustre/obdclass/class_obd.c
+++ b/lustre/obdclass/class_obd.c
@@ -610,6 +610,7 @@ static void cleanup_obdclass(void)
 
         class_handle_cleanup();
         class_exit_uuidlist();
+        obd_zombie_impexp_stop();
 
         memory_leaked = obd_memory_sum();
         pages_leaked = obd_pages_sum();
diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c
index 57eaa22990f6c58678be0f2c4bf548e9d10adfc4..83053aeefb010644f3e2ffc48d42d2a48c6d6738 100644
--- a/lustre/obdclass/genops.c
+++ b/lustre/obdclass/genops.c
@@ -45,9 +45,7 @@ cfs_mem_cache_t *import_cachep;
 struct list_head  obd_zombie_imports;
 struct list_head  obd_zombie_exports;
 spinlock_t        obd_zombie_impexp_lock;
-void            (*obd_zombie_impexp_notify)(void) = NULL;
-EXPORT_SYMBOL(obd_zombie_impexp_notify);
-
+static void obd_zombie_impexp_notify(void);
 
 int (*ptlrpc_put_connection_superhack)(struct ptlrpc_connection *c);
 
@@ -624,8 +622,7 @@ void __class_export_put(struct obd_export *exp)
                 list_add(&exp->exp_obd_chain, &obd_zombie_exports);
                 spin_unlock(&obd_zombie_impexp_lock);
 
-                if (obd_zombie_impexp_notify != NULL)
-                        obd_zombie_impexp_notify();
+                obd_zombie_impexp_notify();
         }
 }
 EXPORT_SYMBOL(__class_export_put);
@@ -766,8 +763,7 @@ void class_import_put(struct obd_import *import)
                 list_add(&import->imp_zombie_chain, &obd_zombie_imports);
                 spin_unlock(&obd_zombie_impexp_lock);
 
-                if (obd_zombie_impexp_notify != NULL)
-                        obd_zombie_impexp_notify();
+                obd_zombie_impexp_notify();
         }
 
         EXIT;
@@ -1282,11 +1278,11 @@ int obd_export_evict_by_uuid(struct obd_device *obd, char *uuid)
 }
 EXPORT_SYMBOL(obd_export_evict_by_uuid);
 
-void obd_zombie_impexp_cull(void) 
+void obd_zombie_impexp_cull(void)
 {
         struct obd_import *import;
         struct obd_export *export;
-        
+
         do {
                 spin_lock (&obd_zombie_impexp_lock);
 
@@ -1297,7 +1293,7 @@ void obd_zombie_impexp_cull(void)
                                             imp_zombie_chain);
                         list_del(&import->imp_zombie_chain);
                 }
-                
+
                 export = NULL;
                 if (!list_empty(&obd_zombie_exports)) {
                         export = list_entry(obd_zombie_exports.next,
@@ -1307,7 +1303,7 @@ void obd_zombie_impexp_cull(void)
                 }
 
                 spin_unlock(&obd_zombie_impexp_lock);
-                
+
                 if (import != NULL)
                         class_import_destroy(import);
 
@@ -1316,11 +1312,121 @@ void obd_zombie_impexp_cull(void)
 
         } while (import != NULL || export != NULL);
 }
-EXPORT_SYMBOL(obd_zombie_impexp_cull);
 
-void obd_zombie_impexp_init(void)
+static struct completion        obd_zombie_start;
+static struct completion        obd_zombie_stop;
+static unsigned long            obd_zombie_flags;
+static cfs_waitq_t              obd_zombie_waitq;
+
+enum {
+        OBD_ZOMBIE_STOP = 1
+};
+
+int obd_zombi_impexp_check(void *arg)
 {
+        int rc;
+
+        spin_lock(&obd_zombie_impexp_lock);
+        rc = list_empty(&obd_zombie_imports) &&
+             list_empty(&obd_zombie_exports) &&
+             !test_bit(OBD_ZOMBIE_STOP, &obd_zombie_flags);
+
+        spin_unlock(&obd_zombie_impexp_lock);
+
+        RETURN(rc);
+}
+
+static void obd_zombie_impexp_notify(void)
+{
+        cfs_waitq_signal(&obd_zombie_waitq);
+}
+
+#ifdef __KERNEL__
+
+static int obd_zombie_impexp_thread(void *unused)
+{
+        int rc;
+
+        if ((rc = cfs_daemonize_ctxt("obd_zombid"))) {
+                complete(&obd_zombie_start);
+                RETURN(rc);
+        }
+
+        complete(&obd_zombie_start);
+
+        while(!test_bit(OBD_ZOMBIE_STOP, &obd_zombie_flags)) {
+                struct l_wait_info lwi = { 0 };
+
+                l_wait_event(obd_zombie_waitq, !obd_zombi_impexp_check(NULL), &lwi);
+
+                obd_zombie_impexp_cull();
+        }
+
+        complete(&obd_zombie_stop);
+
+        RETURN(0);
+}
+
+#else /* ! KERNEL */
+
+static atomic_t zombi_recur = ATOMIC_INIT(0);
+static void *obd_zombi_impexp_work_cb;
+static void *obd_zombi_impexp_idle_cb;
+
+int obd_zombi_impexp_kill(void *arg)
+{
+        int rc = 0;
+
+	if (atomic_inc_return(&zombi_recur) == 1) {
+                obd_zombie_impexp_cull();
+                rc = 1;
+        }
+        atomic_dec(&zombi_recur);
+        return rc;
+}
+
+#endif
+
+int obd_zombie_impexp_init(void)
+{
+        int rc;
+
         CFS_INIT_LIST_HEAD(&obd_zombie_imports);
         CFS_INIT_LIST_HEAD(&obd_zombie_exports);
         spin_lock_init(&obd_zombie_impexp_lock);
+        init_completion(&obd_zombie_start);
+        init_completion(&obd_zombie_stop);
+        cfs_waitq_init(&obd_zombie_waitq);
+
+#ifdef __KERNEL__
+        rc = cfs_kernel_thread(obd_zombie_impexp_thread, NULL, 0);
+        if (rc < 0)
+                RETURN(rc);
+
+        wait_for_completion(&obd_zombie_start);
+#else
+
+        obd_zombi_impexp_work_cb =
+                liblustre_register_wait_callback("obd_zombi_impexp_kill",
+                                                 &obd_zombi_impexp_kill, NULL);
+
+        obd_zombi_impexp_idle_cb =
+                liblustre_register_idle_callback("obd_zombi_impexp_check",
+                                                 &obd_zombi_impexp_check, NULL);
+        rc = 0;
+
+#endif
+        RETURN(rc);
+}
+
+void obd_zombie_impexp_stop(void)
+{
+        set_bit(OBD_ZOMBIE_STOP, &obd_zombie_flags);
+        obd_zombie_impexp_notify();
+#ifdef __KERNEL__
+        wait_for_completion(&obd_zombie_stop);
+#else
+        liblustre_deregister_wait_callback(obd_zombi_impexp_work_cb);
+        liblustre_deregister_idle_callback(obd_zombi_impexp_idle_cb);
+#endif
 }
diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c
index cf8c393752a09d290fb6d205230500562407f3cc..924c6fb48f5d6ccab7440bdb83c049f1e5425910 100644
--- a/lustre/obdclass/obd_config.c
+++ b/lustre/obdclass/obd_config.c
@@ -359,10 +359,10 @@ int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
                obd->obd_name, obd->obd_uuid.uuid);
 
         class_decref(obd);
-        
+
         /* not strictly necessary, but cleans up eagerly */
         obd_zombie_impexp_cull();
-        
+
         RETURN(0);
 }
 
diff --git a/lustre/ptlrpc/import.c b/lustre/ptlrpc/import.c
index 8d60653d6ee0053220e52a018147bd808d099deb..e65d1457a0e2c310ea10089325df34e8d568f88d 100644
--- a/lustre/ptlrpc/import.c
+++ b/lustre/ptlrpc/import.c
@@ -234,6 +234,7 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
                         DEBUG_REQ(D_ERROR, req, "still on delayed list");
                 }
                 spin_unlock(&imp->imp_lock);
+                LASSERT(atomic_read(&imp->imp_inflight) == 0);
         }
 
   out:
diff --git a/lustre/ptlrpc/ptlrpcd.c b/lustre/ptlrpc/ptlrpcd.c
index d0abb2eb85e0fc5f94fb5ace7546ad09c5591e82..5b82f570f03ae206127b07deaeae56d45a4e598d 100644
--- a/lustre/ptlrpc/ptlrpcd.c
+++ b/lustre/ptlrpc/ptlrpcd.c
@@ -97,8 +97,6 @@ static int ptlrpcd_check(struct ptlrpcd_ctl *pc)
         if (test_bit(LIOD_STOP, &pc->pc_flags))
                 RETURN(1);
 
-        obd_zombie_impexp_cull();
-
         spin_lock(&pc->pc_set->set_new_req_lock);
         list_for_each_safe(pos, tmp, &pc->pc_set->set_new_requests) {
                 req = list_entry(pos, struct ptlrpc_request, rq_set_chain);
@@ -176,13 +174,6 @@ static int ptlrpcd(void *arg)
         return 0;
 }
 
-static void ptlrpcd_zombie_impexp_notify(void)
-{
-        LASSERT(ptlrpcd_pc.pc_set != NULL); // call before ptlrpcd inited ?
-
-        cfs_waitq_signal(&ptlrpcd_pc.pc_set->set_waitq);
-}
-
 #else
 
 int ptlrpcd_check_async_rpcs(void *arg)
@@ -233,9 +224,6 @@ static int ptlrpcd_start(char *name, struct ptlrpcd_ctl *pc)
                 RETURN(-ENOMEM);
 
 #ifdef __KERNEL__
-        /* wake ptlrpcd when zombie imports or exports exist */
-        obd_zombie_impexp_notify = ptlrpcd_zombie_impexp_notify;
-        
         rc = cfs_kernel_thread(ptlrpcd, pc, 0);
         if (rc < 0)  {
                 ptlrpc_set_destroy(pc->pc_set);
@@ -260,7 +248,6 @@ static void ptlrpcd_stop(struct ptlrpcd_ctl *pc)
         set_bit(LIOD_STOP, &pc->pc_flags);
         cfs_waitq_signal(&pc->pc_set->set_waitq);
 #ifdef __KERNEL__
-        obd_zombie_impexp_notify = NULL;
         wait_for_completion(&pc->pc_finishing);
 #else
         liblustre_deregister_wait_callback(pc->pc_wait_callback);
diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh
index e3b7f9750a62a8cb414385893b7e4c0c822d8c2c..446852da2511c91de29da28d0baf547ae878d56c 100644
--- a/lustre/tests/conf-sanity.sh
+++ b/lustre/tests/conf-sanity.sh
@@ -800,6 +800,7 @@ test_22() {
 	echo Client mount before any osts are in the logs
 	mount_client $MOUNT
 	check_mount && return 41
+	umount_client $MOUNT
 	pass
 
 	echo Client mount with ost in logs, but none running
diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh
index 0717e187c940b116bd59d230feeeb41aa9ed6151..aa5a1ddd8b92fe89b3638a01333db4f33842b499 100644
--- a/lustre/tests/test-framework.sh
+++ b/lustre/tests/test-framework.sh
@@ -268,16 +268,16 @@ mount_facet() {
     local dev=${facet}_dev
     local opt=${facet}_opt
     echo "Starting ${facet}: ${!opt} $@ ${!dev} ${MOUNT%/*}/${facet}"
+        do_facet ${facet} "lctl set_param debug=$PTLDEBUG; \
+            lctl set_param subsystem_debug=${SUBSYSTEM# }; \
+            lctl set_param debug_mb=${DEBUG_SIZE}; \
+            sync"
+
     do_facet ${facet} mount -t lustre ${!opt} $@ ${!dev} ${MOUNT%/*}/${facet}     
     RC=${PIPESTATUS[0]}
     if [ $RC -ne 0 ]; then
         echo "mount -t lustre $@ ${device} ${MOUNT%/*}/${facet}" 
         echo "Start of ${device} on ${facet} failed ${RC}"
-    else 
-        do_facet ${facet} "lctl set_param debug=$PTLDEBUG; \
-            lctl set_param subsystem_debug=${SUBSYSTEM# }; \
-            lctl set_param debug_mb=${DEBUG_SIZE}; \
-            sync"
     fi
     return $RC
 }
@@ -337,11 +337,12 @@ zconf_mount() {
 
     echo "Starting client: $client: $OPTIONS $device $mnt" 
     do_node $client mkdir -p $mnt
-    do_node $client mount -t lustre $OPTIONS $device $mnt || return 1
-
     do_node $client "lctl set_param debug=$PTLDEBUG;
         lctl set_param subsystem_debug=${SUBSYSTEM# };
         lctl set_param debug_mb=${DEBUG_SIZE}"
+
+    do_node $client mount -t lustre $OPTIONS $device $mnt || return 1
+
     [ -d /r ] && $LCTL modules > /r/tmp/ogdb-$HOSTNAME
     return 0
 }