- lock_kernel();
- ptlrpc_daemonize();
-
- SIGNAL_MASK_LOCK(current, flags);
- sigfillset(¤t->blocked);
- RECALC_SIGPENDING;
- SIGNAL_MASK_UNLOCK(current, flags);
-
- LASSERTF(strlen(data->name) < sizeof(current->comm),
- "name %d > len %d\n",
- (int)strlen(data->name), (int)sizeof(current->comm));
- THREAD_NAME(current->comm, sizeof(current->comm) - 1, "%s", data->name);
- unlock_kernel();
-
- /* Record that the thread is running */
- thread->t_flags = SVC_RUNNING;
- wake_up(&thread->t_ctl_waitq);
-
- /* And now, loop forever, pinging as needed. */
- while (1) {
- unsigned long this_ping = jiffies;
- long time_to_next_ping;
- struct l_wait_info lwi = LWI_TIMEOUT(obd_timeout * HZ,
- NULL, NULL);
- struct list_head *iter;
-
- time_to_next_ping = this_ping + (obd_timeout * HZ) - jiffies;
- down(&pinger_sem);
- list_for_each(iter, &pinger_imports) {
- struct obd_import *imp =
- list_entry(iter, struct obd_import,
- imp_pinger_chain);
- int force, level;
- unsigned long flags;
-
-
- spin_lock_irqsave(&imp->imp_lock, flags);
- level = imp->imp_state;
- force = imp->imp_force_verify;
- if (force)
- imp->imp_force_verify = 0;
- spin_unlock_irqrestore(&imp->imp_lock, flags);
-
- if (imp->imp_next_ping <= this_ping || force) {
- if (level == LUSTRE_IMP_DISCON) {
- /* wait at least a timeout before
- trying recovery again. */
- imp->imp_next_ping =
- ptlrpc_next_ping(imp);
- ptlrpc_initiate_recovery(imp);
- } else if (level != LUSTRE_IMP_FULL ||
- imp->imp_obd->obd_no_recov) {
- CDEBUG(D_HA,
- "not pinging %s (in recovery "
- " or recovery disabled: %s)\n",
- imp->imp_target_uuid.uuid,
- ptlrpc_import_state_name(level));
- } else if (imp->imp_pingable || force) {
- ptlrpc_ping(imp);
- }
-
- } else if (imp->imp_pingable) {
- CDEBUG(D_HA, "don't need to ping %s "
- "(%lu > %lu)\n",
- imp->imp_target_uuid.uuid,
- imp->imp_next_ping, this_ping);
- }
- CDEBUG(D_OTHER, "%s: pingable %d, next_ping %lu(%lu)\n",
- imp->imp_target_uuid.uuid,
- imp->imp_pingable, imp->imp_next_ping, jiffies);
+
+static bool ir_up;
+
+void ptlrpc_pinger_ir_up(void)
+{
+ CDEBUG(D_HA, "IR up\n");
+ ir_up = true;
+}
+EXPORT_SYMBOL(ptlrpc_pinger_ir_up);
+
+void ptlrpc_pinger_ir_down(void)
+{
+ CDEBUG(D_HA, "IR down\n");
+ ir_up = false;
+}
+EXPORT_SYMBOL(ptlrpc_pinger_ir_down);
+
+static void ptlrpc_pinger_process_import(struct obd_import *imp,
+ unsigned long this_ping)
+{
+ int level;
+ int force;
+ int force_next;
+ int suppress;
+
+ spin_lock(&imp->imp_lock);
+
+ level = imp->imp_state;
+ force = imp->imp_force_verify;
+ force_next = imp->imp_force_next_verify;
+ /*
+ * This will be used below only if the import is "FULL".
+ */
+ suppress = ir_up && OCD_HAS_FLAG(&imp->imp_connect_data, PINGLESS);
+
+ imp->imp_force_verify = 0;
+
+ if (cfs_time_aftereq(imp->imp_next_ping - 5 * CFS_TICK, this_ping) &&
+ !force) {
+ spin_unlock(&imp->imp_lock);
+ return;
+ }
+
+ imp->imp_force_next_verify = 0;
+
+ spin_unlock(&imp->imp_lock);
+
+ CDEBUG(level == LUSTRE_IMP_FULL ? D_INFO : D_HA, "%s->%s: level %s/%u "
+ "force %u force_next %u deactive %u pingable %u suppress %u\n",
+ imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd),
+ ptlrpc_import_state_name(level), level, force, force_next,
+ imp->imp_deactive, imp->imp_pingable, suppress);
+
+ if (level == LUSTRE_IMP_DISCON && !imp_is_deactive(imp)) {
+ /* wait for a while before trying recovery again */
+ imp->imp_next_ping = ptlrpc_next_reconnect(imp);
+ if (!imp->imp_no_pinger_recover)
+ ptlrpc_initiate_recovery(imp);
+ } else if (level != LUSTRE_IMP_FULL ||
+ imp->imp_obd->obd_no_recov ||
+ imp_is_deactive(imp)) {
+ CDEBUG(D_HA, "%s->%s: not pinging (in recovery "
+ "or recovery disabled: %s)\n",
+ imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd),
+ ptlrpc_import_state_name(level));
+ if (force) {
+ spin_lock(&imp->imp_lock);
+ imp->imp_force_verify = 1;
+ spin_unlock(&imp->imp_lock);
+ }
+ } else if ((imp->imp_pingable && !suppress) || force_next || force) {
+ ptlrpc_ping(imp);
+ }
+}
+
+static int ptlrpc_pinger_main(void *arg)
+{
+ struct ptlrpc_thread *thread = (struct ptlrpc_thread *)arg;
+ ENTRY;
+
+ /* Record that the thread is running */
+ thread_set_flags(thread, SVC_RUNNING);
+ wake_up(&thread->t_ctl_waitq);
+
+ /* And now, loop forever, pinging as needed. */
+ while (1) {
+ cfs_time_t this_ping = cfs_time_current();
+ struct l_wait_info lwi;
+ cfs_duration_t time_to_next_wake;
+ struct timeout_item *item;
+ struct list_head *iter;
+
+ mutex_lock(&pinger_mutex);
+ list_for_each_entry(item, &timeout_list, ti_chain)
+ item->ti_cb(item, item->ti_cb_data);
+
+ list_for_each(iter, &pinger_imports) {
+ struct obd_import *imp = list_entry(iter,
+ struct obd_import,
+ imp_pinger_chain);
+
+ ptlrpc_pinger_process_import(imp, this_ping);
+ /* obd_timeout might have changed */