示例#1
0
/**
 * Initialize new client connection.
 *
 * This function handles new connection to the OFD. The new export is
 * created (in context of class_connect()) and persistent client data is
 * initialized on storage.
 *
 * \param[in] env	execution environment
 * \param[out] _exp	stores pointer to new export
 * \param[in] obd	OFD device
 * \param[in] cluuid	client UUID
 * \param[in] data	connection data from request
 * \param[in] localdata	client NID
 *
 * \retval		0 if successful
 * \retval		negative value on error
 */
static int ofd_obd_connect(const struct lu_env *env, struct obd_export **_exp,
			   struct obd_device *obd, struct obd_uuid *cluuid,
			   struct obd_connect_data *data, void *localdata)
{
	struct obd_export	*exp;
	struct ofd_device	*ofd;
	struct lustre_handle	 conn = { 0 };
	int			 rc;
	ENTRY;

	if (_exp == NULL || obd == NULL || cluuid == NULL)
		RETURN(-EINVAL);

	ofd = ofd_dev(obd->obd_lu_dev);

	rc = class_connect(&conn, obd, cluuid);
	if (rc)
		RETURN(rc);

	exp = class_conn2export(&conn);
	LASSERT(exp != NULL);

	if (localdata != NULL) {
		rc = nodemap_add_member(*(lnet_nid_t *)localdata, exp);
		if (rc != 0 && rc != -EEXIST)
			GOTO(out, rc);
	} else {
		CDEBUG(D_HA, "%s: cannot find nodemap for client %s: "
		       "nid is null\n", obd->obd_name, cluuid->uuid);
	}

	rc = ofd_parse_connect_data(env, exp, data, true);
	if (rc)
		GOTO(out, rc);

	if (obd->obd_replayable) {
		struct tg_export_data *ted = &exp->exp_target_data;

		memcpy(ted->ted_lcd->lcd_uuid, cluuid,
		       sizeof(ted->ted_lcd->lcd_uuid));
		rc = tgt_client_new(env, exp);
		if (rc != 0)
			GOTO(out, rc);
		ofd_export_stats_init(ofd, exp, localdata);
	}

	CDEBUG(D_HA, "%s: get connection from MDS %d\n", obd->obd_name,
	       data ? data->ocd_group : -1);

out:
	if (rc != 0) {
		class_disconnect(exp);
		nodemap_del_member(exp);
		*_exp = NULL;
	} else {
		*_exp = exp;
	}
	RETURN(rc);
}
示例#2
0
/*
 * obd_connect handler used by the MDT to connect to the master target.
 */
static int qmt_device_obd_connect(const struct lu_env *env,
				  struct obd_export **exp,
				  struct obd_device *obd,
				  struct obd_uuid *cluuid,
				  struct obd_connect_data *data,
				  void *localdata)
{
	struct lustre_handle	conn;
	int			rc;
	ENTRY;

	rc = class_connect(&conn, obd, cluuid);
	if (rc)
		RETURN(rc);

	*exp = class_conn2export(&conn);
	RETURN(0);
}
示例#3
0
文件: mgs_handler.c 项目: LLNL/lustre
/* Establish a connection to the MGS.*/
static int mgs_connect(const struct lu_env *env,
                       struct obd_export **exp, struct obd_device *obd,
                       struct obd_uuid *cluuid, struct obd_connect_data *data,
                       void *localdata)
{
        struct obd_export *lexp;
        struct lustre_handle conn = { 0 };
        int rc;
        ENTRY;

        if (!exp || !obd || !cluuid)
                RETURN(-EINVAL);

        rc = class_connect(&conn, obd, cluuid);
        if (rc)
                RETURN(rc);

        lexp = class_conn2export(&conn);
        LASSERT(lexp);

        mgs_counter_incr(lexp, LPROC_MGS_CONNECT);

        if (data != NULL) {
                data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED;
                lexp->exp_connect_flags = data->ocd_connect_flags;
                data->ocd_version = LUSTRE_VERSION_CODE;
        }

        rc = mgs_export_stats_init(obd, lexp, localdata);

        if (rc) {
                class_disconnect(lexp);
        } else {
                *exp = lexp;
        }

        RETURN(rc);
}
示例#4
0
/*
 * we use exports to track all mdd users
 */
static int mdd_obd_connect(const struct lu_env *env, struct obd_export **exp,
			   struct obd_device *obd, struct obd_uuid *cluuid,
			   struct obd_connect_data *data, void *localdata)
{
	struct mdd_device    *mdd = lu2mdd_dev(obd->obd_lu_dev);
	struct lustre_handle  conn;
	int                   rc;
	ENTRY;

	CDEBUG(D_CONFIG, "connect #%d\n", mdd->mdd_connects);

	rc = class_connect(&conn, obd, cluuid);
	if (rc)
		RETURN(rc);

	*exp = class_conn2export(&conn);

	/* Why should there ever be more than 1 connect? */
	LASSERT(mdd->mdd_connects == 0);
	mdd->mdd_connects++;

	RETURN(0);
}