Ejemplo n.º 1
0
/**
 * Disconnect a connected client.
 *
 * This function terminates the client connection. The client export is
 * disconnected (cleaned up) and client data on persistent storage is removed.
 *
 * \param[in] exp	OBD export
 *
 * \retval		0 if successful
 * \retval		negative value on error
 */
int ofd_obd_disconnect(struct obd_export *exp)
{
	struct ofd_device	*ofd = ofd_exp(exp);
	struct lu_env		 env;
	int			 rc;

	ENTRY;

	LASSERT(exp);
	class_export_get(exp);

	if (!(exp->exp_flags & OBD_OPT_FORCE))
		ofd_grant_sanity_check(ofd_obd(ofd), __FUNCTION__);

	nodemap_del_member(exp);
	rc = server_disconnect_export(exp);

	ofd_grant_discard(exp);

	/* Do not erase record for recoverable client. */
	if (exp->exp_obd->obd_replayable &&
	    (!exp->exp_obd->obd_fail || exp->exp_failed)) {
		rc = lu_env_init(&env, LCT_DT_THREAD);
		if (rc)
			GOTO(out, rc);

		tgt_client_del(&env, exp);
		lu_env_fini(&env);
	}
out:
	class_export_put(exp);
	RETURN(rc);
}
Ejemplo n.º 2
0
/**
 * Re-initialize export upon client reconnection.
 *
 * This function parses connection data from reconnect and resets
 * export statistics.
 *
 * \param[in] env	execution environment
 * \param[in] exp	OBD export
 * \param[in] obd	OFD device
 * \param[in] cluuid	NID of client
 * \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_reconnect(const struct lu_env *env, struct obd_export *exp,
			     struct obd_device *obd, struct obd_uuid *cluuid,
			     struct obd_connect_data *data,
			     void *client_nid)
{
	struct ofd_device	*ofd;
	int			 rc;

	ENTRY;

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

	rc = nodemap_add_member(*(lnet_nid_t *)client_nid, exp);
	if (rc != 0 && rc != -EEXIST)
		RETURN(rc);

	ofd = ofd_dev(obd->obd_lu_dev);

	rc = ofd_parse_connect_data(env, exp, data, false);
	if (rc == 0)
		ofd_export_stats_init(ofd, exp, client_nid);
	else
		nodemap_del_member(exp);

	RETURN(rc);
}
Ejemplo n.º 3
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);
}