Beispiel #1
0
/*
 * Connect a quota master to the backend OSD device.
 *
 * \param env - is the environment passed by the caller
 * \param qmt - is the quota master target to be connected
 * \param cfg - is the configuration log record from which we need to extract
 *              the service name of the backend OSD device to connect to.
 *
 * \retval - 0 on success, appropriate error on failure
 */
static int qmt_connect_to_osd(const struct lu_env *env, struct qmt_device *qmt,
			      struct lustre_cfg *cfg)
{
	struct obd_connect_data	*data = NULL;
	struct obd_device	*obd;
	struct lu_device	*ld = qmt2lu_dev(qmt);
	int			 rc;
	ENTRY;

	LASSERT(qmt->qmt_child_exp == NULL);

	OBD_ALLOC_PTR(data);
	if (data == NULL)
		GOTO(out, rc = -ENOMEM);

	/* look-up OBD device associated with the backend OSD device.
	 * The MDT is kind enough to pass the OBD name in QMT configuration */
	obd = class_name2obd(lustre_cfg_string(cfg, 3));
	if (obd == NULL) {
		CERROR("%s: can't locate backend osd device: %s\n",
		       qmt->qmt_svname, lustre_cfg_string(cfg, 3));
		GOTO(out, rc = -ENOTCONN);
	}

	data->ocd_connect_flags = OBD_CONNECT_VERSION;
	data->ocd_version = LUSTRE_VERSION_CODE;

	/* connect to OSD device */
	rc = obd_connect(NULL, &qmt->qmt_child_exp, obd, &obd->obd_uuid, data,
			 NULL);
	if (rc) {
		CERROR("%s: cannot connect to osd dev %s (%d)\n",
		       qmt->qmt_svname, obd->obd_name, rc);
		GOTO(out, rc);
	}

	/* initialize site (although it isn't used anywhere) and lu_device
	 * pointer to next device */
	qmt->qmt_child = lu2dt_dev(qmt->qmt_child_exp->exp_obd->obd_lu_dev);
	ld->ld_site = qmt->qmt_child_exp->exp_obd->obd_lu_dev->ld_site;
	EXIT;
out:
	if (data)
		OBD_FREE_PTR(data);
	return rc;
}
Beispiel #2
0
static int mdd_connect_to_next(const struct lu_env *env, struct mdd_device *m,
			       const char *nextdev)
{
	struct obd_connect_data *data = NULL;
	struct lu_device	*lud = mdd2lu_dev(m);
	struct obd_device       *obd;
	int			 rc;
	ENTRY;

	LASSERT(m->mdd_child_exp == NULL);

	OBD_ALLOC(data, sizeof(*data));
	if (data == NULL)
		GOTO(out, rc = -ENOMEM);

	obd = class_name2obd(nextdev);
	if (obd == NULL) {
		CERROR("can't locate next device: %s\n", nextdev);
		GOTO(out, rc = -ENOTCONN);
	}

	data->ocd_connect_flags = OBD_CONNECT_VERSION;
	data->ocd_version = LUSTRE_VERSION_CODE;

	rc = obd_connect(NULL, &m->mdd_child_exp, obd, &obd->obd_uuid, data, NULL);
	if (rc) {
		CERROR("cannot connect to next dev %s (%d)\n", nextdev, rc);
		GOTO(out, rc);
	}

	lud->ld_site = m->mdd_child_exp->exp_obd->obd_lu_dev->ld_site;
	LASSERT(lud->ld_site);
	m->mdd_child = lu2dt_dev(m->mdd_child_exp->exp_obd->obd_lu_dev);
	m->mdd_bottom = lu2dt_dev(lud->ld_site->ls_bottom_dev);
	lu_dev_add_linkage(lud->ld_site, lud);

out:
	if (data)
		OBD_FREE(data, sizeof(*data));
	RETURN(rc);
}
Beispiel #3
0
/** Set up a mgc obd to process startup logs
 *
 * \param sb [in] super block of the mgc obd
 *
 * \retval 0 success, otherwise error code
 */
int lustre_start_mgc(struct super_block *sb)
{
	struct obd_connect_data *data = NULL;
	struct lustre_sb_info *lsi = s2lsi(sb);
	struct obd_device *obd;
	struct obd_export *exp;
	struct obd_uuid *uuid;
	class_uuid_t uuidc;
	lnet_nid_t nid;
	char *mgcname = NULL, *niduuid = NULL, *mgssec = NULL;
	char *ptr;
	int recov_bk;
	int rc = 0, i = 0, j, len;

	LASSERT(lsi->lsi_lmd);

	/* Find the first non-lo MGS nid for our MGC name */
	if (IS_SERVER(lsi)) {
		/* mount -o mgsnode=nid */
		ptr = lsi->lsi_lmd->lmd_mgs;
		if (lsi->lsi_lmd->lmd_mgs &&
		    (class_parse_nid(lsi->lsi_lmd->lmd_mgs, &nid, &ptr) == 0)) {
			i++;
		} else if (IS_MGS(lsi)) {
			lnet_process_id_t id;
			while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
				if (LNET_NETTYP(LNET_NIDNET(id.nid)) == LOLND)
					continue;
				nid = id.nid;
				i++;
				break;
			}
		}
	} else { /* client */
		/* Use nids from mount line: uml1,1@elan:uml2,2@elan:/lustre */
		ptr = lsi->lsi_lmd->lmd_dev;
		if (class_parse_nid(ptr, &nid, &ptr) == 0)
			i++;
	}
	if (i == 0) {
		CERROR("No valid MGS nids found.\n");
		return -EINVAL;
	}

	mutex_lock(&mgc_start_lock);

	len = strlen(LUSTRE_MGC_OBDNAME) + strlen(libcfs_nid2str(nid)) + 1;
	OBD_ALLOC(mgcname, len);
	OBD_ALLOC(niduuid, len + 2);
	if (!mgcname || !niduuid)
		GOTO(out_free, rc = -ENOMEM);
	sprintf(mgcname, "%s%s", LUSTRE_MGC_OBDNAME, libcfs_nid2str(nid));

	mgssec = lsi->lsi_lmd->lmd_mgssec ? lsi->lsi_lmd->lmd_mgssec : "";

	OBD_ALLOC_PTR(data);
	if (data == NULL)
		GOTO(out_free, rc = -ENOMEM);

	obd = class_name2obd(mgcname);
	if (obd && !obd->obd_stopping) {
		rc = obd_set_info_async(NULL, obd->obd_self_export,
					strlen(KEY_MGSSEC), KEY_MGSSEC,
					strlen(mgssec), mgssec, NULL);
		if (rc)
			GOTO(out_free, rc);

		/* Re-using an existing MGC */
		atomic_inc(&obd->u.cli.cl_mgc_refcount);

		/* IR compatibility check, only for clients */
		if (lmd_is_client(lsi->lsi_lmd)) {
			int has_ir;
			int vallen = sizeof(*data);
			__u32 *flags = &lsi->lsi_lmd->lmd_flags;

			rc = obd_get_info(NULL, obd->obd_self_export,
					  strlen(KEY_CONN_DATA), KEY_CONN_DATA,
					  &vallen, data, NULL);
			LASSERT(rc == 0);
			has_ir = OCD_HAS_FLAG(data, IMP_RECOV);
			if (has_ir ^ !(*flags & LMD_FLG_NOIR)) {
				/* LMD_FLG_NOIR is for test purpose only */
				LCONSOLE_WARN(
				    "Trying to mount a client with IR setting "
				    "not compatible with current mgc. "
				    "Force to use current mgc setting that is "
				    "IR %s.\n",
				    has_ir ? "enabled" : "disabled");
				if (has_ir)
					*flags &= ~LMD_FLG_NOIR;
				else
					*flags |= LMD_FLG_NOIR;
			}
		}

		recov_bk = 0;
		/* If we are restarting the MGS, don't try to keep the MGC's
		   old connection, or registration will fail. */
		if (IS_MGS(lsi)) {
			CDEBUG(D_MOUNT, "New MGS with live MGC\n");
			recov_bk = 1;
		}

		/* Try all connections, but only once (again).
		   We don't want to block another target from starting
		   (using its local copy of the log), but we do want to connect
		   if at all possible. */
		recov_bk++;
		CDEBUG(D_MOUNT, "%s: Set MGC reconnect %d\n", mgcname,recov_bk);
		rc = obd_set_info_async(NULL, obd->obd_self_export,
					sizeof(KEY_INIT_RECOV_BACKUP),
					KEY_INIT_RECOV_BACKUP,
					sizeof(recov_bk), &recov_bk, NULL);
		GOTO(out, rc = 0);
	}

	CDEBUG(D_MOUNT, "Start MGC '%s'\n", mgcname);

	/* Add the primary nids for the MGS */
	i = 0;
	sprintf(niduuid, "%s_%x", mgcname, i);
	if (IS_SERVER(lsi)) {
		ptr = lsi->lsi_lmd->lmd_mgs;
		if (IS_MGS(lsi)) {
			/* Use local nids (including LO) */
			lnet_process_id_t id;
			while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
				rc = do_lcfg(mgcname, id.nid,
					     LCFG_ADD_UUID, niduuid, 0,0,0);
			}
		} else {
			/* Use mgsnode= nids */
			/* mount -o mgsnode=nid */
			if (lsi->lsi_lmd->lmd_mgs) {
				ptr = lsi->lsi_lmd->lmd_mgs;
			} else if (class_find_param(ptr, PARAM_MGSNODE,
						    &ptr) != 0) {
				CERROR("No MGS nids given.\n");
				GOTO(out_free, rc = -EINVAL);
			}
			while (class_parse_nid(ptr, &nid, &ptr) == 0) {
				rc = do_lcfg(mgcname, nid,
					     LCFG_ADD_UUID, niduuid, 0,0,0);
				i++;
			}
		}
	} else { /* client */
		/* Use nids from mount line: uml1,1@elan:uml2,2@elan:/lustre */
		ptr = lsi->lsi_lmd->lmd_dev;
		while (class_parse_nid(ptr, &nid, &ptr) == 0) {
			rc = do_lcfg(mgcname, nid,
				     LCFG_ADD_UUID, niduuid, 0,0,0);
			i++;
			/* Stop at the first failover nid */
			if (*ptr == ':')
				break;
		}
	}
	if (i == 0) {
		CERROR("No valid MGS nids found.\n");
		GOTO(out_free, rc = -EINVAL);
	}
	lsi->lsi_lmd->lmd_mgs_failnodes = 1;

	/* Random uuid for MGC allows easier reconnects */
	OBD_ALLOC_PTR(uuid);
	ll_generate_random_uuid(uuidc);
	class_uuid_unparse(uuidc, uuid);

	/* Start the MGC */
	rc = lustre_start_simple(mgcname, LUSTRE_MGC_NAME,
				 (char *)uuid->uuid, LUSTRE_MGS_OBDNAME,
				 niduuid, 0, 0);
	OBD_FREE_PTR(uuid);
	if (rc)
		GOTO(out_free, rc);

	/* Add any failover MGS nids */
	i = 1;
	while (ptr && ((*ptr == ':' ||
	       class_find_param(ptr, PARAM_MGSNODE, &ptr) == 0))) {
		/* New failover node */
		sprintf(niduuid, "%s_%x", mgcname, i);
		j = 0;
		while (class_parse_nid_quiet(ptr, &nid, &ptr) == 0) {
			j++;
			rc = do_lcfg(mgcname, nid,
				     LCFG_ADD_UUID, niduuid, 0,0,0);
			if (*ptr == ':')
				break;
		}
		if (j > 0) {
			rc = do_lcfg(mgcname, 0, LCFG_ADD_CONN,
				     niduuid, 0, 0, 0);
			i++;
		} else {
			/* at ":/fsname" */
			break;
		}
	}
	lsi->lsi_lmd->lmd_mgs_failnodes = i;

	obd = class_name2obd(mgcname);
	if (!obd) {
		CERROR("Can't find mgcobd %s\n", mgcname);
		GOTO(out_free, rc = -ENOTCONN);
	}

	rc = obd_set_info_async(NULL, obd->obd_self_export,
				strlen(KEY_MGSSEC), KEY_MGSSEC,
				strlen(mgssec), mgssec, NULL);
	if (rc)
		GOTO(out_free, rc);

	/* Keep a refcount of servers/clients who started with "mount",
	   so we know when we can get rid of the mgc. */
	atomic_set(&obd->u.cli.cl_mgc_refcount, 1);

	/* Try all connections, but only once. */
	recov_bk = 1;
	rc = obd_set_info_async(NULL, obd->obd_self_export,
				sizeof(KEY_INIT_RECOV_BACKUP),
				KEY_INIT_RECOV_BACKUP,
				sizeof(recov_bk), &recov_bk, NULL);
	if (rc)
		/* nonfatal */
		CWARN("can't set %s %d\n", KEY_INIT_RECOV_BACKUP, rc);

	/* We connect to the MGS at setup, and don't disconnect until cleanup */
	data->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_AT |
				  OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV |
				  OBD_CONNECT_LVB_TYPE;

#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 2, 50, 0)
	data->ocd_connect_flags |= OBD_CONNECT_MNE_SWAB;
#else
#warning "LU-1644: Remove old OBD_CONNECT_MNE_SWAB fixup and imp_need_mne_swab"
#endif

	if (lmd_is_client(lsi->lsi_lmd) &&
	    lsi->lsi_lmd->lmd_flags & LMD_FLG_NOIR)
		data->ocd_connect_flags &= ~OBD_CONNECT_IMP_RECOV;
	data->ocd_version = LUSTRE_VERSION_CODE;
	rc = obd_connect(NULL, &exp, obd, &(obd->obd_uuid), data, NULL);
	if (rc) {
		CERROR("connect failed %d\n", rc);
		GOTO(out, rc);
	}

	obd->u.cli.cl_mgc_mgsexp = exp;

out:
	/* Keep the mgc info in the sb. Note that many lsi's can point
	   to the same mgc.*/
	lsi->lsi_mgc = obd;
out_free:
	mutex_unlock(&mgc_start_lock);

	if (data)
		OBD_FREE_PTR(data);
	if (mgcname)
		OBD_FREE(mgcname, len);
	if (niduuid)
		OBD_FREE(niduuid, len + 2);
	return rc;
}
Beispiel #4
0
/* Test client api; open log by name and process */
static int llog_test_6(const struct lu_env *env, struct obd_device *obd,
		       char *name)
{
	struct obd_device	*mgc_obd;
	struct llog_ctxt	*ctxt;
	struct obd_uuid		*mgs_uuid;
	struct obd_export	*exp;
	struct obd_uuid		 uuid = { "LLOG_TEST6_UUID" };
	struct llog_handle	*llh = NULL;
	struct llog_ctxt	*nctxt;
	int			 rc, rc2;

	ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
	LASSERT(ctxt);
	mgs_uuid = &ctxt->loc_exp->exp_obd->obd_uuid;

	CWARN("6a: re-open log %s using client API\n", name);
	mgc_obd = class_find_client_obd(mgs_uuid, LUSTRE_MGC_NAME, NULL);
	if (mgc_obd == NULL) {
		CERROR("6a: no MGC devices connected to %s found.\n",
		       mgs_uuid->uuid);
		GOTO(ctxt_release, rc = -ENOENT);
	}

	rc = obd_connect(NULL, &exp, mgc_obd, &uuid,
			 NULL /* obd_connect_data */, NULL);
	if (rc != -EALREADY) {
		CERROR("6a: connect on connected MGC (%s) failed to return"
		       " -EALREADY", mgc_obd->obd_name);
		if (rc == 0)
			obd_disconnect(exp);
		GOTO(ctxt_release, rc = -EINVAL);
	}

	nctxt = llog_get_context(mgc_obd, LLOG_CONFIG_REPL_CTXT);
	rc = llog_open(env, nctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
	if (rc) {
		CERROR("6a: llog_open failed %d\n", rc);
		GOTO(nctxt_put, rc);
	}

	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
	if (rc) {
		CERROR("6a: llog_init_handle failed %d\n", rc);
		GOTO(parse_out, rc);
	}

	plain_counter = 1; /* llog header is first record */
	CWARN("6b: process log %s using client API\n", name);
	rc = llog_process(env, llh, plain_print_cb, NULL, NULL);
	if (rc)
		CERROR("6b: llog_process failed %d\n", rc);
	CWARN("6b: processed %d records\n", plain_counter);

	rc = verify_handle("6b", llh, plain_counter);
	if (rc)
		GOTO(parse_out, rc);

	plain_counter = 1; /* llog header is first record */
	CWARN("6c: process log %s reversely using client API\n", name);
	rc = llog_reverse_process(env, llh, plain_print_cb, NULL, NULL);
	if (rc)
		CERROR("6c: llog_reverse_process failed %d\n", rc);
	CWARN("6c: processed %d records\n", plain_counter);

	rc = verify_handle("6c", llh, plain_counter);
	if (rc)
		GOTO(parse_out, rc);

parse_out:
	rc2 = llog_close(env, llh);
	if (rc2) {
		CERROR("6: llog_close failed: rc = %d\n", rc2);
		if (rc == 0)
			rc = rc2;
	}
nctxt_put:
	llog_ctxt_put(nctxt);
ctxt_release:
	llog_ctxt_put(ctxt);
	return rc;
}
Beispiel #5
0
/** Set up a mgc obd to process startup logs
 *
 * \param sb [in] super block of the mgc obd
 *
 * \retval 0 success, otherwise error code
 */
int lustre_start_mgc(struct super_block *sb)
{
	struct obd_connect_data *data = NULL;
	struct lustre_sb_info *lsi = s2lsi(sb);
	struct obd_device *obd;
	struct obd_export *exp;
	struct obd_uuid *uuid;
	class_uuid_t uuidc;
	lnet_nid_t nid;
	char nidstr[LNET_NIDSTR_SIZE];
	char *mgcname = NULL, *niduuid = NULL, *mgssec = NULL;
	char *ptr;
	int rc = 0, i = 0, j;

	LASSERT(lsi->lsi_lmd);

	/* Use nids from mount line: uml1,1@elan:uml2,2@elan:/lustre */
	ptr = lsi->lsi_lmd->lmd_dev;
	if (class_parse_nid(ptr, &nid, &ptr) == 0)
		i++;
	if (i == 0) {
		CERROR("No valid MGS nids found.\n");
		return -EINVAL;
	}

	mutex_lock(&mgc_start_lock);

	libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
	mgcname = kasprintf(GFP_NOFS,
			    "%s%s", LUSTRE_MGC_OBDNAME, nidstr);
	niduuid = kasprintf(GFP_NOFS, "%s_%x", mgcname, i);
	if (!mgcname || !niduuid) {
		rc = -ENOMEM;
		goto out_free;
	}

	mgssec = lsi->lsi_lmd->lmd_mgssec ? lsi->lsi_lmd->lmd_mgssec : "";

	data = kzalloc(sizeof(*data), GFP_NOFS);
	if (!data) {
		rc = -ENOMEM;
		goto out_free;
	}

	obd = class_name2obd(mgcname);
	if (obd && !obd->obd_stopping) {
		int recov_bk;

		rc = obd_set_info_async(NULL, obd->obd_self_export,
					strlen(KEY_MGSSEC), KEY_MGSSEC,
					strlen(mgssec), mgssec, NULL);
		if (rc)
			goto out_free;

		/* Re-using an existing MGC */
		atomic_inc(&obd->u.cli.cl_mgc_refcount);

		/* IR compatibility check, only for clients */
		if (lmd_is_client(lsi->lsi_lmd)) {
			int has_ir;
			int vallen = sizeof(*data);
			__u32 *flags = &lsi->lsi_lmd->lmd_flags;

			rc = obd_get_info(NULL, obd->obd_self_export,
					  strlen(KEY_CONN_DATA), KEY_CONN_DATA,
					  &vallen, data, NULL);
			LASSERT(rc == 0);
			has_ir = OCD_HAS_FLAG(data, IMP_RECOV);
			if (has_ir ^ !(*flags & LMD_FLG_NOIR)) {
				/* LMD_FLG_NOIR is for test purpose only */
				LCONSOLE_WARN(
					"Trying to mount a client with IR setting not compatible with current mgc. Force to use current mgc setting that is IR %s.\n",
					has_ir ? "enabled" : "disabled");
				if (has_ir)
					*flags &= ~LMD_FLG_NOIR;
				else
					*flags |= LMD_FLG_NOIR;
			}
		}

		recov_bk = 0;

		/* Try all connections, but only once (again).
		   We don't want to block another target from starting
		   (using its local copy of the log), but we do want to connect
		   if at all possible. */
		recov_bk++;
		CDEBUG(D_MOUNT, "%s: Set MGC reconnect %d\n", mgcname,
		       recov_bk);
		rc = obd_set_info_async(NULL, obd->obd_self_export,
					sizeof(KEY_INIT_RECOV_BACKUP),
					KEY_INIT_RECOV_BACKUP,
					sizeof(recov_bk), &recov_bk, NULL);
		rc = 0;
		goto out;
	}

	CDEBUG(D_MOUNT, "Start MGC '%s'\n", mgcname);

	/* Add the primary nids for the MGS */
	i = 0;
	/* Use nids from mount line: uml1,1@elan:uml2,2@elan:/lustre */
	ptr = lsi->lsi_lmd->lmd_dev;
	while (class_parse_nid(ptr, &nid, &ptr) == 0) {
		rc = do_lcfg(mgcname, nid,
			     LCFG_ADD_UUID, niduuid, NULL, NULL, NULL);
		i++;
		/* Stop at the first failover nid */
		if (*ptr == ':')
			break;
	}
	if (i == 0) {
		CERROR("No valid MGS nids found.\n");
		rc = -EINVAL;
		goto out_free;
	}
	lsi->lsi_lmd->lmd_mgs_failnodes = 1;

	/* Random uuid for MGC allows easier reconnects */
	uuid = kzalloc(sizeof(*uuid), GFP_NOFS);
	if (!uuid) {
		rc = -ENOMEM;
		goto out_free;
	}

	ll_generate_random_uuid(uuidc);
	class_uuid_unparse(uuidc, uuid);

	/* Start the MGC */
	rc = lustre_start_simple(mgcname, LUSTRE_MGC_NAME,
				 (char *)uuid->uuid, LUSTRE_MGS_OBDNAME,
				 niduuid, NULL, NULL);
	kfree(uuid);
	if (rc)
		goto out_free;

	/* Add any failover MGS nids */
	i = 1;
	while (ptr && ((*ptr == ':' ||
	       class_find_param(ptr, PARAM_MGSNODE, &ptr) == 0))) {
		/* New failover node */
		sprintf(niduuid, "%s_%x", mgcname, i);
		j = 0;
		while (class_parse_nid_quiet(ptr, &nid, &ptr) == 0) {
			j++;
			rc = do_lcfg(mgcname, nid,
				     LCFG_ADD_UUID, niduuid, NULL, NULL, NULL);
			if (*ptr == ':')
				break;
		}
		if (j > 0) {
			rc = do_lcfg(mgcname, 0, LCFG_ADD_CONN,
				     niduuid, NULL, NULL, NULL);
			i++;
		} else {
			/* at ":/fsname" */
			break;
		}
	}
	lsi->lsi_lmd->lmd_mgs_failnodes = i;

	obd = class_name2obd(mgcname);
	if (!obd) {
		CERROR("Can't find mgcobd %s\n", mgcname);
		rc = -ENOTCONN;
		goto out_free;
	}

	rc = obd_set_info_async(NULL, obd->obd_self_export,
				strlen(KEY_MGSSEC), KEY_MGSSEC,
				strlen(mgssec), mgssec, NULL);
	if (rc)
		goto out_free;

	/* Keep a refcount of servers/clients who started with "mount",
	   so we know when we can get rid of the mgc. */
	atomic_set(&obd->u.cli.cl_mgc_refcount, 1);

	/* We connect to the MGS at setup, and don't disconnect until cleanup */
	data->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_AT |
				  OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV |
				  OBD_CONNECT_LVB_TYPE;

#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 2, 50, 0)
	data->ocd_connect_flags |= OBD_CONNECT_MNE_SWAB;
#else
#warning "LU-1644: Remove old OBD_CONNECT_MNE_SWAB fixup and imp_need_mne_swab"
#endif

	if (lmd_is_client(lsi->lsi_lmd) &&
	    lsi->lsi_lmd->lmd_flags & LMD_FLG_NOIR)
		data->ocd_connect_flags &= ~OBD_CONNECT_IMP_RECOV;
	data->ocd_version = LUSTRE_VERSION_CODE;
	rc = obd_connect(NULL, &exp, obd, &(obd->obd_uuid), data, NULL);
	if (rc) {
		CERROR("connect failed %d\n", rc);
		goto out;
	}

	obd->u.cli.cl_mgc_mgsexp = exp;

out:
	/* Keep the mgc info in the sb. Note that many lsi's can point
	   to the same mgc.*/
	lsi->lsi_mgc = obd;
out_free:
	mutex_unlock(&mgc_start_lock);

	kfree(data);
	kfree(mgcname);
	kfree(niduuid);
	return rc;
}
Beispiel #6
0
int liblustre_process_log(struct config_llog_instance *cfg,
                          char *mgsnid, char *profile,
                          int allow_recov)
{
        struct lustre_cfg_bufs bufs;
        struct lustre_cfg *lcfg;
        char  *peer = "MGS_UUID";
        struct obd_device *obd;
        struct obd_export *exp;
        char  *name = "mgc_dev";
        class_uuid_t uuid;
        struct obd_uuid mgc_uuid;
        struct llog_ctxt *ctxt;
        lnet_nid_t nid = 0;
        char *mdsnid;
        int err, rc = 0;
        struct obd_connect_data *ocd = NULL;
        ENTRY;

        ll_generate_random_uuid(uuid);
        class_uuid_unparse(uuid, &mgc_uuid);

        nid = libcfs_str2nid(mgsnid);
        if (nid == LNET_NID_ANY) {
                CERROR("Can't parse NID %s\n", mgsnid);
                RETURN(-EINVAL);
        }

        lustre_cfg_bufs_reset(&bufs, NULL);
        lustre_cfg_bufs_set_string(&bufs, 1, peer);
        lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs);
        lcfg->lcfg_nid = nid;
        rc = class_process_config(lcfg);
        lustre_cfg_free(lcfg);
        if (rc < 0)
                GOTO(out, rc);

        lustre_cfg_bufs_reset(&bufs, name);
        lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MGC_NAME);
        lustre_cfg_bufs_set_string(&bufs, 2, mgc_uuid.uuid);
        lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs);
        rc = class_process_config(lcfg);
        lustre_cfg_free(lcfg);
        if (rc < 0)
                GOTO(out_del_uuid, rc);

        lustre_cfg_bufs_reset(&bufs, name);
        lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MGS_OBDNAME);
        lustre_cfg_bufs_set_string(&bufs, 2, peer);
        lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
        rc = class_process_config(lcfg);
        lustre_cfg_free(lcfg);
        if (rc < 0)
                GOTO(out_detach, rc);

        while ((mdsnid = strsep(&mgsnid, ","))) {
                nid = libcfs_str2nid(mdsnid);
                lustre_cfg_bufs_reset(&bufs, NULL);
                lustre_cfg_bufs_set_string(&bufs, 1, libcfs_nid2str(nid));
                lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs);
                lcfg->lcfg_nid = nid;
                rc = class_process_config(lcfg);
                lustre_cfg_free(lcfg);
                if (rc) {
                        CERROR("Add uuid for %s failed %d\n",
                               libcfs_nid2str(nid), rc);
                        continue;
                }

                lustre_cfg_bufs_reset(&bufs, name);
                lustre_cfg_bufs_set_string(&bufs, 1, libcfs_nid2str(nid));
                lcfg = lustre_cfg_new(LCFG_ADD_CONN, &bufs);
                lcfg->lcfg_nid = nid;
                rc = class_process_config(lcfg);
                lustre_cfg_free(lcfg);
                if (rc) {
                        CERROR("Add conn for %s failed %d\n",
                               libcfs_nid2str(nid), rc);
                        continue;
                }
        }

        obd = class_name2obd(name);
        if (obd == NULL)
                GOTO(out_cleanup, rc = -EINVAL);

        OBD_ALLOC(ocd, sizeof(*ocd));
        if (ocd == NULL)
                GOTO(out_cleanup, rc = -ENOMEM);

	ocd->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_AT |
				 OBD_CONNECT_FULL20;
        ocd->ocd_version = LUSTRE_VERSION_CODE;

        rc = obd_connect(NULL, &exp, obd, &mgc_uuid, ocd, NULL);
        if (rc) {
                CERROR("cannot connect to %s at %s: rc = %d\n",
                       LUSTRE_MGS_OBDNAME, mgsnid, rc);
                GOTO(out_cleanup, rc);
        }

        ctxt = llog_get_context(exp->exp_obd, LLOG_CONFIG_REPL_CTXT);
        cfg->cfg_flags |= CFG_F_COMPAT146;
	rc = class_config_parse_llog(NULL, ctxt, profile, cfg);
        llog_ctxt_put(ctxt);
        if (rc) {
                CERROR("class_config_parse_llog failed: rc = %d\n", rc);
        }

        /* We don't so much care about errors in cleaning up the config llog
         * connection, as we have already read the config by this point. */
        err = obd_disconnect(exp);
        if (err)
                CERROR("obd_disconnect failed: rc = %d\n", err);

out_cleanup:
        if (ocd)
                OBD_FREE(ocd, sizeof(*ocd));

        lustre_cfg_bufs_reset(&bufs, name);
        lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
        err = class_process_config(lcfg);
        lustre_cfg_free(lcfg);
        if (err)
                CERROR("md_cleanup failed: rc = %d\n", err);

out_detach:
        lustre_cfg_bufs_reset(&bufs, name);
        lcfg = lustre_cfg_new(LCFG_DETACH, &bufs);
        err = class_process_config(lcfg);
        lustre_cfg_free(lcfg);
        if (err)
                CERROR("md_detach failed: rc = %d\n", err);

out_del_uuid:
        lustre_cfg_bufs_reset(&bufs, name);
        lustre_cfg_bufs_set_string(&bufs, 1, peer);
        lcfg = lustre_cfg_new(LCFG_DEL_UUID, &bufs);
        err = class_process_config(lcfg);
        if (err)
                CERROR("del MDC UUID failed: rc = %d\n", err);
        lustre_cfg_free(lcfg);
out:

        RETURN(rc);
}
Beispiel #7
0
/* Test client api; open log by name and process */
static int llog_test_6(struct obd_device *obd, char *name)
{
        struct obd_device *mgc_obd;
        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
        struct obd_uuid *mgs_uuid = &ctxt->loc_exp->exp_obd->obd_uuid;
        struct obd_export *exp;
        struct obd_uuid uuid = {"LLOG_TEST6_UUID"};
        struct llog_handle *llh = NULL;
        struct llog_ctxt *nctxt;
        int rc;

        CWARN("6a: re-open log %s using client API\n", name);
        mgc_obd = class_find_client_obd(mgs_uuid, LUSTRE_MGC_NAME, NULL);
        if (mgc_obd == NULL) {
                CERROR("6: no MGC devices connected to %s found.\n",
                       mgs_uuid->uuid);
                GOTO(ctxt_release, rc = -ENOENT);
        }

        rc = obd_connect(NULL, &exp, mgc_obd, &uuid,
                         NULL /* obd_connect_data */, NULL);
        if (rc != -EALREADY) {
                CERROR("6: connect on connected MDC (%s) failed to return"
                       " -EALREADY", mgc_obd->obd_name);
                if (rc == 0)
                        obd_disconnect(exp);
                GOTO(ctxt_release, rc = -EINVAL);
        }

        nctxt = llog_get_context(mgc_obd, LLOG_CONFIG_REPL_CTXT);
        rc = llog_create(nctxt, &llh, NULL, name);
        if (rc) {
                CERROR("6: llog_create failed %d\n", rc);
                llog_ctxt_put(nctxt);
                GOTO(ctxt_release, rc);
        }

        rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
        if (rc) {
                CERROR("6: llog_init_handle failed %d\n", rc);
                GOTO(parse_out, rc);
        }

        rc = llog_process(llh, plain_print_cb, NULL, NULL);
        if (rc)
                CERROR("6: llog_process failed %d\n", rc);

        rc = llog_reverse_process(llh, plain_print_cb, NULL, NULL);
        if (rc)
                CERROR("6: llog_reverse_process failed %d\n", rc);

parse_out:
        rc = llog_close(llh);
        llog_ctxt_put(nctxt);
        if (rc) {
                CERROR("6: llog_close failed: rc = %d\n", rc);
        }
ctxt_release:
        llog_ctxt_put(ctxt);
        RETURN(rc);
}