return &tti->tti_buf;
}
+static inline bool tgt_is_multimodrpcs_record(struct lu_target *tgt,
+ struct lsd_client_data *lcd)
+{
+ return tgt->lut_lsd.lsd_feature_incompat & OBD_INCOMPAT_MULTI_RPCS &&
+ lcd->lcd_generation != 0;
+}
+
/**
* Allocate in-memory data for client slot related to export.
*/
exp->exp_obd->obd_name, ted->ted_lr_idx);
LBUG();
}
-
- if (tgt_is_multimodrpcs_client(exp) && !exp->exp_obd->obd_stopping)
- atomic_dec(&lut->lut_num_clients);
}
EXPORT_SYMBOL(tgt_client_free);
list_splice_init(&client_list, &tgt->lut_obd->obd_final_req_queue);
spin_unlock(&tgt->lut_obd->obd_recovery_task_lock);
- /** Clear MULTI RPCS incompatibility flag if
- * - target is MDT and
- * - there is no client to recover or the recovery was aborted
+ /**
+ * Clear MULTI RPCS incompatibility flag if there is no multi-rpcs
+ * client in last_rcvd file
*/
- if (!strncmp(tgt->lut_obd->obd_type->typ_name, LUSTRE_MDT_NAME, 3) &&
- (atomic_read(&tgt->lut_obd->obd_max_recoverable_clients) == 0 ||
- tgt->lut_obd->obd_abort_recovery))
+ if (atomic_read(&tgt->lut_num_clients) == 0)
tgt->lut_lsd.lsd_feature_incompat &= ~OBD_INCOMPAT_MULTI_RPCS;
/** update server epoch */
if (tgt_is_multimodrpcs_client(exp)) {
/* Set MULTI RPCS incompatibility flag to prevent previous
* Lustre versions to mount a target with reply_data file */
- atomic_inc(&tgt->lut_num_clients);
if (!(tgt->lut_lsd.lsd_feature_incompat &
OBD_INCOMPAT_MULTI_RPCS)) {
tgt->lut_lsd.lsd_feature_incompat |=
RETURN(-ENOSPC);
rc = tgt_client_data_update(env, exp);
- if (rc)
+ if (rc) {
CERROR("%s: Failed to write client lcd at idx %d, rc %d\n",
tgt->lut_obd->obd_name, idx, rc);
+ RETURN(rc);
+ }
- RETURN(rc);
+ if (tgt_is_multimodrpcs_client(exp))
+ atomic_inc(&tgt->lut_num_clients);
+
+ RETURN(0);
}
EXPORT_SYMBOL(tgt_client_new);
tgt->lut_obd->obd_name, idx);
LBUG();
}
- atomic_inc(&tgt->lut_num_clients);
CDEBUG(D_INFO, "%s: client at idx %d with UUID '%s' added, "
"generation %d\n",
RETURN(rc);
}
+ /* Race between an eviction and a disconnection ?*/
+ mutex_lock(&ted->ted_lcd_lock);
+ if (ted->ted_lcd->lcd_uuid[0] == '\0') {
+ mutex_unlock(&ted->ted_lcd_lock);
+ RETURN(rc);
+ }
+
memset(ted->ted_lcd->lcd_uuid, 0, sizeof ted->ted_lcd->lcd_uuid);
+ mutex_unlock(&ted->ted_lcd_lock);
+
rc = tgt_client_data_update(env, exp);
+ if (!rc && tgt_is_multimodrpcs_record(tgt, ted->ted_lcd))
+ atomic_dec(&tgt->lut_num_clients);
+
CDEBUG(rc == 0 ? D_INFO : D_ERROR,
"%s: zeroing out client %s at idx %u (%llu), rc %d\n",
tgt->lut_obd->obd_name, ted->ted_lcd->lcd_uuid,
spin_unlock(&exp->exp_lock);
atomic_inc(&obd->obd_max_recoverable_clients);
- if (tgt->lut_lsd.lsd_feature_incompat &
- OBD_INCOMPAT_MULTI_RPCS &&
- lcd->lcd_generation != 0) {
+ if (tgt_is_multimodrpcs_record(tgt, lcd)) {
+ atomic_inc(&tgt->lut_num_clients);
+
/* compute the highest valid client generation */
generation = max(generation, lcd->lcd_generation);
/* fill client_generation <-> export hash table */
PTLDEBUG=${PTLDEBUG:--1}
MOUNT_2=${MOUNT_2:-"yes"}
+LR_READER=${LR_READER:-"$LUSTRE/utils/lr_reader"}
LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
. $LUSTRE/tests/test-framework.sh
}
run_test 32 "gap in update llog shouldn't break recovery"
+last_rcvd_check_incompat_flag() {
+ local facet="$1"
+ local flag2check="$2"
+ local dev=$(facet_device $facet)
+ local incompat
+
+ incompat=$(do_facet $facet $LR_READER $dev |
+ awk '/feature_incompat:/ {print $2}')
+ echo "last_rcvd in $dev: incompat = $incompat"
+
+ return $(( (incompat & flag2check) != flag2check ))
+}
+
+
+test_33() { # LU-15935
+ [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
+
+ clients_up
+ stop mds1
+
+ # check for OBD_INCOMPAT_MULTI_RPCS (0x400) in last_rcvd
+ last_rcvd_check_incompat_flag mds1 0x400 ||
+ error "1st failover: OBD_INCOMPAT_MULTI_RPCS is not set on MDT0000 last_rcvd"
+
+ # lose 1 client while the MDT failover
+ umount -f $MOUNT2
+
+ mount_facet mds1
+ wait_clients_import_state "$HOSTNAME" mds1 "\(REPLAY_WAIT\|REPLAY_LOCKS\)"
+
+ do_facet mds1 $LCTL --device $(convert_facet2label mds1) abort_recovery
+ wait_clients_import_state "$HOSTNAME" mds1 "FULL"
+ stop mds1
+
+ last_rcvd_check_incompat_flag mds1 0x400 ||
+ error "2sd failover: OBD_INCOMPAT_MULTI_RPCS is not set on MDT0000 last_rcvd"
+
+ mount_facet mds1
+ zconf_mount $HOSTNAME $MOUNT2
+ wait_clients_import_state "$HOSTNAME" mds1 "FULL"
+}
+run_test 33 "Check for OBD_INCOMPAT_MULTI_RPCS in last_rcvd after abort_recovery"
+
complete $SECONDS
SLEEP=$((SECONDS - $NOW))
[ $SLEEP -lt $TIMEOUT ] && sleep $SLEEP