for (i = 0; i < numrec; i++) {
struct nvmf_disc_log_entry *e = &log->entries[i];
bool discover = false;
+ bool disconnect;
nvme_ctrl_t child;
int tmo = defcfg->keep_alive_tmo;
continue;
/* Skip connect if the transport types don't match */
- if (strcmp(nvme_ctrl_get_transport(c), nvmf_trtype_str(e->trtype)))
+ if (strcmp(nvme_ctrl_get_transport(c),
+ nvmf_trtype_str(e->trtype)))
continue;
if (e->subtype == NVME_NQN_DISC ||
- e->subtype == NVME_NQN_CURR)
+ e->subtype == NVME_NQN_CURR) {
+ __u16 eflags = le16_to_cpu(e->eflags);
+ /*
+ * Does this discovery controller return the
+ * same information?
+ */
+ if (eflags & NVMF_DISC_EFLAGS_DUPRETINFO)
+ continue;
+
+ /* Are we supposed to keep the discovery
+ * controller around? */
+ disconnect = !persistent;
+
+ if (strcmp(e->subnqn, NVME_DISC_SUBSYS_NAME)) {
+ /*
+ * Does this discovery controller doesn't
+ * support explicit persistent connection?
+ */
+ if (!(eflags & NVMF_DISC_EFLAGS_EPCSD))
+ disconnect = true;
+ }
+
set_discovery_kato(defcfg);
+ } else {
+ /* NVME_NQN_NVME */
+ disconnect = false;
+ }
errno = 0;
child = nvmf_connect_disc_entry(h, e, defcfg,
if (discover)
__discover(child, defcfg, raw,
true, persistent, flags);
- if (e->subtype != NVME_NQN_NVME &&
- !persistent) {
+ if (disconnect) {
nvme_disconnect_ctrl(child);
nvme_free_ctrl(child);
}