@@ -794,9 +794,6 @@ static void nfs_Init(const nfs_start_info_t *p_start_info)
/* Save Ganesha thread credentials with Frank's routine for later use */
fsal_save_ganesha_credentials();
- /* Start grace period */
- nfs_start_grace(NULL);
-
/* RPC Initialisation - exits on failure */
nfs_Init_svc();
LogInfo(COMPONENT_INIT, "RPC resources successfully initialized");
@@ -239,6 +239,12 @@ int nfs_libmain(const char *ganesha_conf,
*/
nfs4_recovery_init();
+ /* Start grace period */
+ nfs_start_grace(NULL);
+
+ /* Wait for enforcement to begin */
+ nfs_wait_for_grace_enforcement();
+
/* Load export entries from parsed file
* returns the number of export entries.
*/
@@ -484,6 +484,12 @@ int main(int argc, char *argv[])
*/
nfs4_recovery_init();
+ /* Start grace period */
+ nfs_start_grace(NULL);
+
+ /* Wait for enforcement to begin */
+ nfs_wait_for_grace_enforcement();
+
/* Load export entries from parsed file
* returns the number of export entries.
*/
@@ -280,6 +280,38 @@ void nfs_try_lift_grace(void)
}
}
+static pthread_cond_t enforcing_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t enforcing_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* Poll every 5s, just in case we miss the wakeup for some reason */
+void nfs_wait_for_grace_enforcement(void)
+{
+ nfs_grace_start_t gsp = { .event = EVENT_JUST_GRACE };
+
+ pthread_mutex_lock(&enforcing_mutex);
+ nfs_try_lift_grace();
+ while (nfs_in_grace() && !nfs_grace_enforcing()) {
+ struct timespec timeo = { .tv_sec = time(NULL) + 5,
+ .tv_nsec = 0 };
+
+ pthread_cond_timedwait(&enforcing_cond, &enforcing_mutex,
+ &timeo);
+
+ pthread_mutex_unlock(&enforcing_mutex);
+ nfs_start_grace(&gsp);
+ nfs_try_lift_grace();
+ pthread_mutex_lock(&enforcing_mutex);
+ }
+ pthread_mutex_unlock(&enforcing_mutex);
+}
+
+void nfs_notify_grace_waiters(void)
+{
+ pthread_mutex_lock(&enforcing_mutex);
+ pthread_cond_broadcast(&enforcing_cond);
+ pthread_mutex_unlock(&enforcing_mutex);
+}
+
/**
* @brief Create an entry in the recovery directory
*
@@ -978,6 +978,8 @@ bool nfs_in_grace(void);
bool simple_try_lift_grace(void);
void nfs_maybe_start_grace(void);
void nfs_try_lift_grace(void);
+void nfs_wait_for_grace_enforcement(void);
+void nfs_notify_grace_waiters(void);
void nfs4_add_clid(nfs_client_id_t *);
void nfs4_rm_clid(nfs_client_id_t *);
void nfs4_recovery_reclaim_complete(nfs_client_id_t *clientid);