/* Connect flags */
-#define OBD_CONNECT_RDONLY 0x1ULL
+#define OBD_CONNECT_RDONLY 0x01ULL
+#define OBD_CONNECT_BLOCK 0x02ULL /* block until connect completes */
#define OBD_CONNECT_SRVLOCK 0x10ULL /* server takes locks for client */
#define MDS_CONNECT_SUPPORTED (OBD_CONNECT_RDONLY)
int ptlrpc_init_import(struct obd_import *imp);
int ptlrpc_disconnect_import(struct obd_import *imp);
int ptlrpc_import_recovery_state_machine(struct obd_import *imp);
+int ptlrpc_wait_for_connect(struct obd_import *imp);
/* ptlrpc/pack_generic.c */
int lustre_msg_swabbed(struct lustre_msg *msg);
}
ptlrpc_pinger_add_import(imp);
- EXIT;
if (rc) {
out_ldlm:
}
out_sem:
up(&cli->cl_sem);
- return rc;
+
+ if (!rc && (ocd->ocd_connect_flags & OBD_CONNECT_BLOCK)) {
+ rc = ptlrpc_wait_for_connect(imp);
+ if (rc) {
+ CERROR("Blocking connect failed %d, disconnecting\n",
+ rc);
+ /* connection was fully set up; do the full
+ disconnect. We already dropped our ref above
+ though, so take another. */
+ exp = class_conn2export(dlm_handle);
+ client_disconnect_export(exp);
+ }
+ }
+
+ RETURN(rc);
}
int client_disconnect_export(struct obd_export *exp)
else
rc = ptlrpc_disconnect_import(imp);
- EXIT;
out_no_disconnect:
err = class_disconnect(exp);
if (!rc && err)
GOTO(out, rc);
lustre_cfg_bufs_reset(&bufs, name);
- lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MDC_NAME);
+ lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MDC_NAME);//FIXME connect to mgc
lustre_cfg_bufs_set_string(&bufs, 2, mdc_uuid.uuid);
lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs);
rc = class_process_config(lcfg);
RETURN(-EINVAL);
}
if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
- strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
+ strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
+ strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
CERROR("can't add connection on non-client dev\n");
RETURN(-EINVAL);
}
len = file->f_dentry->d_inode->i_size;
CDEBUG(D_MOUNT, "Have %s, size %lu\n", MOUNT_DATA_FILE, len);
if (len != sizeof(*ldd)) {
- CERROR("disk data size does not match: see %lu expect %lu\n",
+ CERROR("disk data size does not match: see %lu expect %u\n",
len, sizeof(*ldd));
GOTO(out_close, err = -EINVAL);
}
struct lustre_handle mgc_conn = {0, };
struct obd_export *exp = NULL;
struct llog_ctxt *ctxt;
+ struct obd_connect_data ocd;
+ struct obd_import *imp = mgc->u.cli.cl_import;
+
int err, rc;
LASSERT(mgc);
CDEBUG(D_MOUNT, "parsing config log %s\n", profile);
- err = obd_connect(&mgc_conn, mgc, &(mgc->obd_uuid), NULL);
+ ocd.ocd_connect_flags = OBD_CONNECT_BLOCK;
+ err = obd_connect(&mgc_conn, mgc, &(mgc->obd_uuid), &ocd);
if (!err) {
+ /* Take a reference */
exp = class_conn2export(&mgc_conn);
+ LASSERT(exp->exp_obd == mgc);
ctxt = llog_get_context(exp->exp_obd, LLOG_CONFIG_REPL_CTXT);
} else {
/* If we couldn't connect to the MGS, try reading a copy
EXIT;
}
+/* still trying to connect */
+static int ptlrpc_import_in_connect(struct obd_import *imp)
+{
+ unsigned long flags;
+ int in_connect = 0;
+ spin_lock_irqsave(&imp->imp_lock, flags);
+ if (!imp->imp_invalid &&
+ (imp->imp_state == LUSTRE_IMP_CONNECTING ||
+ imp->imp_state == LUSTRE_IMP_DISCON))
+ in_connect = 1;
+ spin_unlock_irqrestore(&imp->imp_lock, flags);
+ return in_connect;
+}
+
+int ptlrpc_wait_for_connect(struct obd_import *imp)
+{
+ struct l_wait_info lwi;
+ int err;
+
+ lwi = LWI_INTR(NULL, NULL);
+ err = l_wait_event(imp->imp_recovery_waitq,
+ !ptlrpc_import_in_connect(imp), &lwi);
+ CERROR("wait got %d (%s, %d)\n", err,
+ ptlrpc_import_state_name(imp->imp_state),
+ imp->imp_invalid);
+ return (imp->imp_invalid ? -ETIMEDOUT : 0);
+}
+EXPORT_SYMBOL(ptlrpc_wait_for_connect);
+
static int import_select_connection(struct obd_import *imp)
{
struct obd_import_conn *imp_conn;
int ptlrpc_connect_import(struct obd_import *imp, char * new_uuid)
{
struct obd_device *obd = imp->imp_obd;
- int initial_connect = 0;
+ int initial_connect = 0, first_try;
int rc;
__u64 committed_before_reconnect = 0;
struct ptlrpc_request *request;
GOTO(out, rc);
}
+ first_try = (imp->imp_conn_current == NULL);
rc = import_select_connection(imp);
if (rc)
GOTO(out, rc);
+ if ((imp->imp_connect_data.ocd_connect_flags & OBD_CONNECT_BLOCK) &&
+ initial_connect && !first_try &&
+ (imp->imp_conn_current == list_entry(imp->imp_conn_list.next,
+ struct obd_import_conn,
+ oic_item))) {
+ /* Never connected, tried everyone, and nobody answered.
+ Give up; in-progress ops will fail (probably EIO) */
+ LCONSOLE_ERROR("All %d connections for %s failed; I am "
+ "deactivating the import.\n",
+ imp->imp_conn_cnt - 1,
+ imp->imp_target_uuid.uuid);
+ ptlrpc_deactivate_import(imp);
+ /* for ptlrpc_wait_for_connect */
+ wake_up(&imp->imp_recovery_waitq);
+ GOTO(out, rc = -ETIMEDOUT);
+ }
+
request = ptlrpc_prep_req(imp, imp->imp_connect_op, 4, size, tmp);
if (!request)
GOTO(out, rc = -ENOMEM);