import.c
来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,348 行 · 第 1/4 页
C
1,348 行
list_for_each_entry(conn, &imp->imp_conn_list, oic_item) { CDEBUG(D_HA, "%s: connect to NID %s last attempt "LPU64"\n", imp->imp_obd->obd_name, libcfs_nid2str(conn->oic_conn->c_peer.nid), conn->oic_last_attempt); /* Don't thrash connections */ if (cfs_time_before_64(cfs_time_current_64(), conn->oic_last_attempt + cfs_time_seconds(CONNECTION_SWITCH_MIN))) { continue; } /* If we have not tried this connection since the the last successful attempt, go with this one */ if ((conn->oic_last_attempt == 0) || cfs_time_beforeq_64(conn->oic_last_attempt, imp->imp_last_success_conn)) { imp_conn = conn; tried_all = 0; break; } /* If all of the connections have already been tried since the last successful connection; just choose the least recently used */ if (!imp_conn) imp_conn = conn; else if (cfs_time_before_64(conn->oic_last_attempt, imp_conn->oic_last_attempt)) imp_conn = conn; } /* if not found, simply choose the current one */ if (!imp_conn) { LASSERT(imp->imp_conn_current); imp_conn = imp->imp_conn_current; tried_all = 0; } LASSERT(imp_conn->oic_conn); /* If we've tried everything, and we're back to the beginning of the list, increase our timeout and try again. It will be reset when we do finally connect. (FIXME: really we should wait for all network state associated with the last connection attempt to drain before trying to reconnect on it.) */ if (tried_all && (imp->imp_conn_list.next == &imp_conn->oic_item) && !imp->imp_recon_bk /* not retrying */) { if (at_get(&imp->imp_at.iat_net_latency) < CONNECTION_SWITCH_MAX) { at_add(&imp->imp_at.iat_net_latency, at_get(&imp->imp_at.iat_net_latency) + CONNECTION_SWITCH_INC); } LASSERT(imp_conn->oic_last_attempt); CWARN("%s: tried all connections, increasing latency to %ds\n", imp->imp_obd->obd_name, at_get(&imp->imp_at.iat_net_latency)); } imp_conn->oic_last_attempt = cfs_time_current_64(); /* switch connection, don't mind if it's same as the current one */ if (imp->imp_connection) ptlrpc_put_connection(imp->imp_connection); imp->imp_connection = ptlrpc_connection_addref(imp_conn->oic_conn); dlmexp = class_conn2export(&imp->imp_dlm_handle); LASSERT(dlmexp != NULL); if (dlmexp->exp_connection) ptlrpc_put_connection(dlmexp->exp_connection); dlmexp->exp_connection = ptlrpc_connection_addref(imp_conn->oic_conn); class_export_put(dlmexp); if (imp->imp_conn_current != imp_conn) { if (imp->imp_conn_current) LCONSOLE_INFO("Changing connection for %s to %s/%s\n", imp->imp_obd->obd_name, imp_conn->oic_uuid.uuid, libcfs_nid2str(imp_conn->oic_conn->c_peer.nid)); imp->imp_conn_current = imp_conn; } CDEBUG(D_HA, "%s: import %p using connection %s/%s\n", imp->imp_obd->obd_name, imp, imp_conn->oic_uuid.uuid, libcfs_nid2str(imp_conn->oic_conn->c_peer.nid)); spin_unlock(&imp->imp_lock); RETURN(0);}int ptlrpc_connect_import(struct obd_import *imp, char *new_uuid){ struct obd_device *obd = imp->imp_obd; int initial_connect = 0; int rc; __u64 committed_before_reconnect = 0; struct ptlrpc_request *request; int size[] = { sizeof(struct ptlrpc_body), sizeof(imp->imp_obd->u.cli.cl_target_uuid), sizeof(obd->obd_uuid), sizeof(imp->imp_dlm_handle), sizeof(imp->imp_connect_data) }; char *tmp[] = { NULL, obd2cli_tgt(imp->imp_obd), obd->obd_uuid.uuid, (char *)&imp->imp_dlm_handle, (char *)&imp->imp_connect_data }; struct ptlrpc_connect_async_args *aa; ENTRY; spin_lock(&imp->imp_lock); if (imp->imp_state == LUSTRE_IMP_CLOSED) { spin_unlock(&imp->imp_lock); CERROR("can't connect to a closed import\n"); RETURN(-EINVAL); } else if (imp->imp_state == LUSTRE_IMP_FULL) { spin_unlock(&imp->imp_lock); CERROR("already connected\n"); RETURN(0); } else if (imp->imp_state == LUSTRE_IMP_CONNECTING) { spin_unlock(&imp->imp_lock); CERROR("already connecting\n"); RETURN(-EALREADY); } IMPORT_SET_STATE_NOLOCK(imp, LUSTRE_IMP_CONNECTING); imp->imp_conn_cnt++; imp->imp_resend_replay = 0; if (!lustre_handle_is_used(&imp->imp_remote_handle)) initial_connect = 1; else committed_before_reconnect = imp->imp_peer_committed_transno; spin_unlock(&imp->imp_lock); if (new_uuid) { struct obd_uuid uuid; obd_str2uuid(&uuid, new_uuid); rc = import_set_conn_priority(imp, &uuid); if (rc) GOTO(out, rc); } rc = import_select_connection(imp); if (rc) GOTO(out, rc); /* last in connection list */ if (imp->imp_conn_current->oic_item.next == &imp->imp_conn_list) { if (imp->imp_initial_recov_bk && initial_connect) { CDEBUG(D_HA, "Last connection attempt (%d) for %s\n", imp->imp_conn_cnt, obd2cli_tgt(imp->imp_obd)); /* Don't retry if connect fails */ rc = 0; obd_set_info_async(obd->obd_self_export, strlen(KEY_INIT_RECOV), KEY_INIT_RECOV, sizeof(rc), &rc, NULL); } if (imp->imp_recon_bk) { CDEBUG(D_HA, "Last reconnection attempt (%d) for %s\n", imp->imp_conn_cnt, obd2cli_tgt(imp->imp_obd)); spin_lock(&imp->imp_lock); imp->imp_last_recon = 1; spin_unlock(&imp->imp_lock); } } /* Reset connect flags to the originally requested flags, in case * the server is updated on-the-fly we will get the new features. */ imp->imp_connect_data.ocd_connect_flags = imp->imp_connect_flags_orig; imp->imp_msghdr_flags &= ~MSGHDR_AT_SUPPORT; rc = obd_reconnect(imp->imp_obd->obd_self_export, obd, &obd->obd_uuid, &imp->imp_connect_data); if (rc) GOTO(out, rc); request = ptlrpc_prep_req(imp, LUSTRE_OBD_VERSION, imp->imp_connect_op, 5, size, tmp); if (!request) GOTO(out, rc = -ENOMEM);#ifndef __KERNEL__ lustre_msg_add_op_flags(request->rq_reqmsg, MSG_CONNECT_LIBCLIENT);#endif if (imp->imp_msg_magic == LUSTRE_MSG_MAGIC_V1) lustre_msg_add_op_flags(request->rq_reqmsg, MSG_CONNECT_NEXT_VER); request->rq_send_state = LUSTRE_IMP_CONNECTING; /* Allow a slightly larger reply for future growth compatibility */ size[REPLY_REC_OFF] = sizeof(struct obd_connect_data) + 16 * sizeof(__u64); ptlrpc_req_set_repsize(request, 2, size); request->rq_interpret_reply = ptlrpc_connect_interpret; CLASSERT(sizeof (*aa) <= sizeof (request->rq_async_args)); aa = (struct ptlrpc_connect_async_args *)&request->rq_async_args; memset(aa, 0, sizeof *aa); aa->pcaa_peer_committed = committed_before_reconnect; aa->pcaa_initial_connect = initial_connect; if (aa->pcaa_initial_connect) { spin_lock(&imp->imp_lock); imp->imp_replayable = 1; spin_unlock(&imp->imp_lock); if (AT_OFF) /* AT will use INITIAL_CONNECT_TIMEOUT the first time, adaptive after that. */ request->rq_timeout = INITIAL_CONNECT_TIMEOUT; } DEBUG_REQ(D_RPCTRACE, request, "%sconnect request %d", aa->pcaa_initial_connect ? "initial " : "re", imp->imp_conn_cnt); ptlrpcd_add_req(request); rc = 0;out: if (rc != 0) { IMPORT_SET_STATE(imp, LUSTRE_IMP_DISCON); } RETURN(rc);}EXPORT_SYMBOL(ptlrpc_connect_import);static void ptlrpc_maybe_ping_import_soon(struct obd_import *imp){#ifdef __KERNEL__ struct obd_import_conn *imp_conn;#endif int wake_pinger = 0; ENTRY; spin_lock(&imp->imp_lock); if (list_empty(&imp->imp_conn_list)) GOTO(unlock, 0);#ifdef __KERNEL__ imp_conn = list_entry(imp->imp_conn_list.prev, struct obd_import_conn, oic_item); /* XXX: When the failover node is the primary node, it is possible * to have two identical connections in imp_conn_list. We must * compare not conn's pointers but NIDs, otherwise we can defeat * connection throttling. (See bug 14774.) */ if (imp->imp_conn_current->oic_conn->c_self != imp_conn->oic_conn->c_self) { ptlrpc_ping_import_soon(imp); wake_pinger = 1; }#else /* liblustre has no pinger thead, so we wakup pinger anyway */ wake_pinger = 1;#endif unlock: spin_unlock(&imp->imp_lock); if (wake_pinger) ptlrpc_pinger_wake_up(); EXIT;}static int ptlrpc_connect_interpret(struct ptlrpc_request *request, void * data, int rc){ struct ptlrpc_connect_async_args *aa = data; struct obd_import *imp = request->rq_import; struct client_obd *cli = &imp->imp_obd->u.cli; struct lustre_handle old_hdl; int msg_flags; ENTRY; spin_lock(&imp->imp_lock); if (imp->imp_state == LUSTRE_IMP_CLOSED) { spin_unlock(&imp->imp_lock); RETURN(0); } spin_unlock(&imp->imp_lock); if (rc) GOTO(out, rc); LASSERT(imp->imp_conn_current); msg_flags = lustre_msg_get_op_flags(request->rq_repmsg); /* All imports are pingable */ spin_lock(&imp->imp_lock); imp->imp_pingable = 1; if (aa->pcaa_initial_connect) { if (msg_flags & MSG_CONNECT_REPLAYABLE) { imp->imp_replayable = 1; spin_unlock(&imp->imp_lock); CDEBUG(D_HA, "connected to replayable target: %s\n", obd2cli_tgt(imp->imp_obd)); } else { imp->imp_replayable = 0; spin_unlock(&imp->imp_lock); } if ((request->rq_reqmsg->lm_magic == LUSTRE_MSG_MAGIC_V1 && msg_flags & MSG_CONNECT_NEXT_VER) || request->rq_reqmsg->lm_magic == LUSTRE_MSG_MAGIC_V2) { imp->imp_msg_magic = LUSTRE_MSG_MAGIC_V2; CDEBUG(D_RPCTRACE, "connect to %s with lustre_msg_v2\n", obd2cli_tgt(imp->imp_obd)); } else { CDEBUG(D_RPCTRACE, "connect to %s with lustre_msg_v1\n", obd2cli_tgt(imp->imp_obd)); } imp->imp_remote_handle = *lustre_msg_get_handle(request->rq_repmsg); IMPORT_SET_STATE(imp, LUSTRE_IMP_FULL); spin_lock(&imp->imp_lock); if (imp->imp_invalid) { spin_unlock(&imp->imp_lock); ptlrpc_activate_import(imp); } else { spin_unlock(&imp->imp_lock); } GOTO(finish, rc = 0); } else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?