Esempio n. 1
0
char *
libcfs_nid2str(lnet_nid_t nid)
{
        __u32             addr = LNET_NIDADDR(nid);
        __u32             net = LNET_NIDNET(nid);
        int               lnd = LNET_NETTYP(net);
        int               nnum = LNET_NETNUM(net);
        struct netstrfns *nf;
        char             *str;
        int               nob;

        if (nid == LNET_NID_ANY)
                return "<?>";

        nf = libcfs_lnd2netstrfns(lnd);
        str = libcfs_next_nidstring();

        if (nf == NULL)
                snprintf(str, LNET_NIDSTR_SIZE, "%x@<%u:%u>", addr, lnd, nnum);
        else {
                nf->nf_addr2str(addr, str);
                nob = strlen(str);
                if (nnum == 0)
                        snprintf(str + nob, LNET_NIDSTR_SIZE - nob, "@%s",
                                 nf->nf_name);
                else
                        snprintf(str + nob, LNET_NIDSTR_SIZE - nob, "@%s%u",
                                 nf->nf_name, nnum);
        }

        return str;
}
Esempio n. 2
0
void
libcfs_net2str2(__u32 net, char str[LNET_NIDSTR_SIZE])
{
	int               lnd = LNET_NETTYP(net);
	int               num = LNET_NETNUM(net);
	struct netstrfns *nf  = libcfs_lnd2netstrfns(lnd);

	if (nf == NULL)
		snprintf(str, LNET_NIDSTR_SIZE, "<%u:%u>", lnd, num);
	else if (num == 0)
		snprintf(str, LNET_NIDSTR_SIZE, "%s", nf->nf_name);
	else
		snprintf(str, LNET_NIDSTR_SIZE, "%s%u", nf->nf_name, num);
}
Esempio n. 3
0
char *
libcfs_net2str(__u32 net)
{
        int               lnd = LNET_NETTYP(net);
        int               num = LNET_NETNUM(net);
        struct netstrfns *nf  = libcfs_lnd2netstrfns(lnd);
        char             *str = libcfs_next_nidstring();

        if (nf == NULL)
                snprintf(str, LNET_NIDSTR_SIZE, "<%u:%u>", lnd, num);
        else if (num == 0)
                snprintf(str, LNET_NIDSTR_SIZE, "%s", nf->nf_name);
        else
                snprintf(str, LNET_NIDSTR_SIZE, "%s%u", nf->nf_name, num);

        return str;
}
Esempio n. 4
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;
}
Esempio n. 5
0
static int __init init_lustre_lite(void)
{
	int i, rc, seed[2];
	struct timeval tv;
	lnet_process_id_t lnet_id;

	CLASSERT(sizeof(LUSTRE_VOLATILE_HDR) == LUSTRE_VOLATILE_HDR_LEN + 1);

	/* print an address of _any_ initialized kernel symbol from this
	 * module, to allow debugging with gdb that doesn't support data
	 * symbols from modules.*/
	CDEBUG(D_INFO, "Lustre client module (%p).\n",
	       &lustre_super_operations);

        rc = ll_init_inodecache();
        if (rc)
                return -ENOMEM;
        ll_file_data_slab = cfs_mem_cache_create("ll_file_data",
                                                 sizeof(struct ll_file_data), 0,
                                                 CFS_SLAB_HWCACHE_ALIGN);
        if (ll_file_data_slab == NULL) {
                ll_destroy_inodecache();
                return -ENOMEM;
        }

        ll_remote_perm_cachep = cfs_mem_cache_create("ll_remote_perm_cache",
                                                  sizeof(struct ll_remote_perm),
                                                      0, 0);
        if (ll_remote_perm_cachep == NULL) {
                cfs_mem_cache_destroy(ll_file_data_slab);
                ll_file_data_slab = NULL;
                ll_destroy_inodecache();
                return -ENOMEM;
        }

        ll_rmtperm_hash_cachep = cfs_mem_cache_create("ll_rmtperm_hash_cache",
                                                   REMOTE_PERM_HASHSIZE *
                                                   sizeof(cfs_list_t),
                                                   0, 0);
        if (ll_rmtperm_hash_cachep == NULL) {
                cfs_mem_cache_destroy(ll_remote_perm_cachep);
                ll_remote_perm_cachep = NULL;
                cfs_mem_cache_destroy(ll_file_data_slab);
                ll_file_data_slab = NULL;
                ll_destroy_inodecache();
                return -ENOMEM;
        }

        proc_lustre_fs_root = proc_lustre_root ?
                              lprocfs_register("llite", proc_lustre_root, NULL, NULL) : NULL;

        lustre_register_client_fill_super(ll_fill_super);
        lustre_register_kill_super_cb(ll_kill_super);

        lustre_register_client_process_config(ll_process_config);

        cfs_get_random_bytes(seed, sizeof(seed));

        /* Nodes with small feet have little entropy
         * the NID for this node gives the most entropy in the low bits */
        for (i=0; ; i++) {
                if (LNetGetId(i, &lnet_id) == -ENOENT) {
                        break;
                }
                if (LNET_NETTYP(LNET_NIDNET(lnet_id.nid)) != LOLND) {
                        seed[0] ^= LNET_NIDADDR(lnet_id.nid);
                }
        }

        cfs_gettimeofday(&tv);
        cfs_srand(tv.tv_sec ^ seed[0], tv.tv_usec ^ seed[1]);

        init_timer(&ll_capa_timer);
        ll_capa_timer.function = ll_capa_timer_callback;
        rc = ll_capa_thread_start();
        /*
         * XXX normal cleanup is needed here.
         */
        if (rc == 0)
                rc = vvp_global_init();

        return rc;
}
Esempio n. 6
0
static int __init lustre_init(void)
{
	struct proc_dir_entry *entry;
	lnet_process_id_t lnet_id;
	struct timeval tv;
	int i, rc, seed[2];

	CLASSERT(sizeof(LUSTRE_VOLATILE_HDR) == LUSTRE_VOLATILE_HDR_LEN + 1);

	/* print an address of _any_ initialized kernel symbol from this
	 * module, to allow debugging with gdb that doesn't support data
	 * symbols from modules.*/
	CDEBUG(D_INFO, "Lustre client module (%p).\n",
	       &lustre_super_operations);

	ll_inode_cachep = kmem_cache_create("lustre_inode_cache",
					    sizeof(struct ll_inode_info),
					    0, SLAB_HWCACHE_ALIGN, NULL);
	if (ll_inode_cachep == NULL)
		GOTO(out_cache, rc = -ENOMEM);

	ll_file_data_slab = kmem_cache_create("ll_file_data",
						 sizeof(struct ll_file_data), 0,
						 SLAB_HWCACHE_ALIGN, NULL);
	if (ll_file_data_slab == NULL)
		GOTO(out_cache, rc = -ENOMEM);

	ll_remote_perm_cachep = kmem_cache_create("ll_remote_perm_cache",
						  sizeof(struct ll_remote_perm),
						  0, 0, NULL);
	if (ll_remote_perm_cachep == NULL)
		GOTO(out_cache, rc = -ENOMEM);

	ll_rmtperm_hash_cachep = kmem_cache_create("ll_rmtperm_hash_cache",
						   REMOTE_PERM_HASHSIZE *
						   sizeof(struct hlist_head),
						   0, 0, NULL);
	if (ll_rmtperm_hash_cachep == NULL)
		GOTO(out_cache, rc = -ENOMEM);

	entry = lprocfs_register("llite", proc_lustre_root, NULL, NULL);
	if (IS_ERR(entry)) {
		rc = PTR_ERR(entry);
		CERROR("cannot register '/proc/fs/lustre/llite': rc = %d\n",
		       rc);
		GOTO(out_cache, rc);
	}

	proc_lustre_fs_root = entry;

	cfs_get_random_bytes(seed, sizeof(seed));

	/* Nodes with small feet have little entropy. The NID for this
	 * node gives the most entropy in the low bits. */
	for (i = 0;; i++) {
		if (LNetGetId(i, &lnet_id) == -ENOENT)
			break;

		if (LNET_NETTYP(LNET_NIDNET(lnet_id.nid)) != LOLND)
			seed[0] ^= LNET_NIDADDR(lnet_id.nid);
	}

	do_gettimeofday(&tv);
	cfs_srand(tv.tv_sec ^ seed[0], tv.tv_usec ^ seed[1]);

	rc = vvp_global_init();
	if (rc != 0)
		GOTO(out_proc, rc);

	cl_inode_fini_env = cl_env_alloc(&cl_inode_fini_refcheck,
					 LCT_REMEMBER | LCT_NOREF);
	if (IS_ERR(cl_inode_fini_env))
		GOTO(out_vvp, rc = PTR_ERR(cl_inode_fini_env));

	cl_inode_fini_env->le_ctx.lc_cookie = 0x4;

	rc = ll_xattr_init();
	if (rc != 0)
		GOTO(out_inode_fini_env, rc);

	lustre_register_client_fill_super(ll_fill_super);
	lustre_register_kill_super_cb(ll_kill_super);
	lustre_register_client_process_config(ll_process_config);

	RETURN(0);

out_inode_fini_env:
	cl_env_put(cl_inode_fini_env, &cl_inode_fini_refcheck);
out_vvp:
	vvp_global_fini();
out_proc:
	lprocfs_remove(&proc_lustre_fs_root);
out_cache:
	if (ll_inode_cachep != NULL)
		kmem_cache_destroy(ll_inode_cachep);

	if (ll_file_data_slab != NULL)
		kmem_cache_destroy(ll_file_data_slab);

	if (ll_remote_perm_cachep != NULL)
		kmem_cache_destroy(ll_remote_perm_cachep);

	if (ll_rmtperm_hash_cachep != NULL)
		kmem_cache_destroy(ll_rmtperm_hash_cachep);

	return rc;
}
Esempio n. 7
0
int lustre_lnet_config_route(char *nw, char *gw, int hops, int prio,
			     int seq_no, struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data data;
	lnet_nid_t gateway_nid;
	int rc = LUSTRE_CFG_RC_NO_ERR;
	__u32 net = LNET_NIDNET(LNET_NID_ANY);
	char err_str[LNET_MAX_STR_LEN];

	snprintf(err_str, sizeof(err_str), "\"Success\"");

	if (nw == NULL || gw == NULL) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"missing mandatory parameter(s): '%s'\"",
			 (nw == NULL && gw == NULL) ? "network, gateway" :
			 (nw == NULL) ? "network" : "gateway");
		rc = LUSTRE_CFG_RC_MISSING_PARAM;
		goto out;
	}

	net = libcfs_str2net(nw);
	if (net == LNET_NIDNET(LNET_NID_ANY)) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot parse net %s\"", nw);
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	if (LNET_NETTYP(net) == CIBLND    ||
	    LNET_NETTYP(net) == OPENIBLND ||
	    LNET_NETTYP(net) == IIBLND    ||
	    LNET_NETTYP(net) == VIBLND) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	gateway_nid = libcfs_str2nid(gw);
	if (gateway_nid == LNET_NID_ANY) {
		snprintf(err_str,
			sizeof(err_str),
			"\"cannot parse gateway NID '%s'\"", gw);
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	if (hops == -1) {
		/* hops is undefined */
		hops = LNET_UNDEFINED_HOPS;
	} else if (hops < 1 || hops > 255) {
		snprintf(err_str,
			sizeof(err_str),
			"\"invalid hop count %d, must be between 1 and 255\"",
			hops);
		rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
		goto out;
	}

	if (prio == -1) {
		prio = 0;
	} else if (prio < 0) {
		snprintf(err_str,
			 sizeof(err_str),
			"\"invalid priority %d, must be greater than 0\"",
			prio);
		rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
		goto out;
	}

	LIBCFS_IOC_INIT_V2(data, cfg_hdr);
	data.cfg_net = net;
	data.cfg_config_u.cfg_route.rtr_hop = hops;
	data.cfg_config_u.cfg_route.rtr_priority = prio;
	data.cfg_nid = gateway_nid;

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_ROUTE, &data);
	if (rc != 0) {
		rc = -errno;
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot add route: %s\"", strerror(errno));
		goto out;
	}

out:
	cYAML_build_error(rc, seq_no, ADD_CMD, "route", err_str, err_rc);

	return rc;
}
Esempio n. 8
0
int lustre_lnet_show_route(char *nw, char *gw, int hops, int prio, int detail,
			   int seq_no, struct cYAML **show_rc,
			   struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data data;
	lnet_nid_t gateway_nid;
	int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
	int l_errno = 0;
	__u32 net = LNET_NIDNET(LNET_NID_ANY);
	int i;
	struct cYAML *root = NULL, *route = NULL, *item = NULL;
	struct cYAML *first_seq = NULL;
	char err_str[LNET_MAX_STR_LEN];
	bool exist = false;

	snprintf(err_str, sizeof(err_str),
		 "\"out of memory\"");

	if (nw != NULL) {
		net = libcfs_str2net(nw);
		if (net == LNET_NIDNET(LNET_NID_ANY)) {
			snprintf(err_str,
				 sizeof(err_str),
				 "\"cannot parse net '%s'\"", nw);
			rc = LUSTRE_CFG_RC_BAD_PARAM;
			goto out;
		}

		if (LNET_NETTYP(net) == CIBLND    ||
		    LNET_NETTYP(net) == OPENIBLND ||
		    LNET_NETTYP(net) == IIBLND    ||
		    LNET_NETTYP(net) == VIBLND) {
			snprintf(err_str,
				 sizeof(err_str),
				 "\"obsolete LNet type '%s'\"",
				 libcfs_lnd2str(net));
			rc = LUSTRE_CFG_RC_BAD_PARAM;
			goto out;
		}
	} else {
		/* show all routes without filtering on net */
		net = LNET_NIDNET(LNET_NID_ANY);
	}

	if (gw != NULL) {
		gateway_nid = libcfs_str2nid(gw);
		if (gateway_nid == LNET_NID_ANY) {
			snprintf(err_str,
				 sizeof(err_str),
				 "\"cannot parse gateway NID '%s'\"", gw);
			rc = LUSTRE_CFG_RC_BAD_PARAM;
			goto out;
		}
	} else
		/* show all routes with out filtering on gateway */
		gateway_nid = LNET_NID_ANY;

	if ((hops < 1 && hops != -1) || hops > 255) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"invalid hop count %d, must be between 0 and 256\"",
			 hops);
		rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
		goto out;
	}

	/* create struct cYAML root object */
	root = cYAML_create_object(NULL, NULL);
	if (root == NULL)
		goto out;

	route = cYAML_create_seq(root, "route");
	if (route == NULL)
		goto out;

	for (i = 0;; i++) {
		LIBCFS_IOC_INIT_V2(data, cfg_hdr);
		data.cfg_count = i;

		rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_ROUTE, &data);
		if (rc != 0) {
			l_errno = errno;
			break;
		}

		/* filter on provided data */
		if (net != LNET_NIDNET(LNET_NID_ANY) &&
		    net != data.cfg_net)
			continue;

		if (gateway_nid != LNET_NID_ANY &&
		    gateway_nid != data.cfg_nid)
			continue;

		if (hops != -1 &&
		    hops != data.cfg_config_u.cfg_route.rtr_hop)
			continue;

		if (prio != -1 &&
		    prio != data.cfg_config_u.cfg_route.rtr_priority)
			continue;

		/* default rc to -1 incase we hit the goto */
		rc = -1;
		exist = true;

		item = cYAML_create_seq_item(route);
		if (item == NULL)
			goto out;

		if (first_seq == NULL)
			first_seq = item;

		if (cYAML_create_string(item, "net",
					libcfs_net2str(data.cfg_net)) == NULL)
			goto out;

		if (cYAML_create_string(item, "gateway",
					libcfs_nid2str(data.cfg_nid)) == NULL)
			goto out;

		if (detail) {
			if (cYAML_create_number(item, "hop",
						data.cfg_config_u.cfg_route.
							rtr_hop) ==
			    NULL)
				goto out;

			if (cYAML_create_number(item, "priority",
						data.cfg_config_u.
						cfg_route.rtr_priority) == NULL)
				goto out;

			if (cYAML_create_string(item, "state",
						data.cfg_config_u.cfg_route.
							rtr_flags ?
						"up" : "down") == NULL)
				goto out;
		}
	}

	/* print output iff show_rc is not provided */
	if (show_rc == NULL)
		cYAML_print_tree(root);

	if (l_errno != ENOENT) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot get routes: %s\"",
			 strerror(l_errno));
		rc = -l_errno;
		goto out;
	} else
		rc = LUSTRE_CFG_RC_NO_ERR;

	snprintf(err_str, sizeof(err_str), "\"success\"");
out:
	if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
		cYAML_free_tree(root);
	} else if (show_rc != NULL && *show_rc != NULL) {
		struct cYAML *show_node;
		/* find the route node, if one doesn't exist then
		 * insert one.  Otherwise add to the one there
		 */
		show_node = cYAML_get_object_item(*show_rc, "route");
		if (show_node != NULL && cYAML_is_sequence(show_node)) {
			cYAML_insert_child(show_node, first_seq);
			free(route);
			free(root);
		} else if (show_node == NULL) {
			cYAML_insert_sibling((*show_rc)->cy_child,
						route);
			free(root);
		} else {
			cYAML_free_tree(root);
		}
	} else {
		*show_rc = root;
	}

	cYAML_build_error(rc, seq_no, SHOW_CMD, "route", err_str, err_rc);

	return rc;
}
Esempio n. 9
0
int lustre_lnet_del_route(char *nw, char *gw,
			  int seq_no, struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data data;
	lnet_nid_t gateway_nid;
	int rc = LUSTRE_CFG_RC_NO_ERR;
	__u32 net = LNET_NIDNET(LNET_NID_ANY);
	char err_str[LNET_MAX_STR_LEN];

	snprintf(err_str, sizeof(err_str), "\"Success\"");

	if (nw == NULL || gw == NULL) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"missing mandatory parameter(s): '%s'\"",
			 (nw == NULL && gw == NULL) ? "network, gateway" :
			 (nw == NULL) ? "network" : "gateway");
		rc = LUSTRE_CFG_RC_MISSING_PARAM;
		goto out;
	}

	net = libcfs_str2net(nw);
	if (net == LNET_NIDNET(LNET_NID_ANY)) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot parse net '%s'\"", nw);
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	if (LNET_NETTYP(net) == CIBLND    ||
	    LNET_NETTYP(net) == OPENIBLND ||
	    LNET_NETTYP(net) == IIBLND    ||
	    LNET_NETTYP(net) == VIBLND) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	gateway_nid = libcfs_str2nid(gw);
	if (gateway_nid == LNET_NID_ANY) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot parse gateway NID '%s'\"", gw);
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	LIBCFS_IOC_INIT_V2(data, cfg_hdr);
	data.cfg_net = net;
	data.cfg_nid = gateway_nid;

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_ROUTE, &data);
	if (rc != 0) {
		rc = -errno;
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot delete route: %s\"", strerror(errno));
		goto out;
	}

out:
	cYAML_build_error(rc, seq_no, DEL_CMD, "route", err_str, err_rc);

	return rc;
}
Esempio n. 10
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 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) {
		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, 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);
Esempio n. 11
0
static int __init lustre_init(void)
{
	struct lnet_process_id lnet_id;
	struct timespec64 ts;
	int i, rc, seed[2];

	BUILD_BUG_ON(sizeof(LUSTRE_VOLATILE_HDR) != LUSTRE_VOLATILE_HDR_LEN + 1);

	/* print an address of _any_ initialized kernel symbol from this
	 * module, to allow debugging with gdb that doesn't support data
	 * symbols from modules.
	 */
	CDEBUG(D_INFO, "Lustre client module (%p).\n",
	       &lustre_super_operations);

	rc = -ENOMEM;
	ll_inode_cachep = kmem_cache_create("lustre_inode_cache",
					    sizeof(struct ll_inode_info), 0,
					    SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
					    NULL);
	if (!ll_inode_cachep)
		goto out_cache;

	ll_file_data_slab = kmem_cache_create("ll_file_data",
					      sizeof(struct ll_file_data), 0,
					      SLAB_HWCACHE_ALIGN, NULL);
	if (!ll_file_data_slab)
		goto out_cache;

	llite_root = debugfs_create_dir("llite", debugfs_lustre_root);
	if (IS_ERR_OR_NULL(llite_root)) {
		rc = llite_root ? PTR_ERR(llite_root) : -ENOMEM;
		llite_root = NULL;
		goto out_cache;
	}

	llite_kset = kset_create_and_add("llite", NULL, lustre_kobj);
	if (!llite_kset) {
		rc = -ENOMEM;
		goto out_debugfs;
	}

	cfs_get_random_bytes(seed, sizeof(seed));

	/* Nodes with small feet have little entropy. The NID for this
	 * node gives the most entropy in the low bits
	 */
	for (i = 0;; i++) {
		if (LNetGetId(i, &lnet_id) == -ENOENT)
			break;

		if (LNET_NETTYP(LNET_NIDNET(lnet_id.nid)) != LOLND)
			seed[0] ^= LNET_NIDADDR(lnet_id.nid);
	}

	ktime_get_ts64(&ts);
	cfs_srand(ts.tv_sec ^ seed[0], ts.tv_nsec ^ seed[1]);

	rc = vvp_global_init();
	if (rc != 0)
		goto out_sysfs;

	cl_inode_fini_env = cl_env_alloc(&cl_inode_fini_refcheck,
					 LCT_REMEMBER | LCT_NOREF);
	if (IS_ERR(cl_inode_fini_env)) {
		rc = PTR_ERR(cl_inode_fini_env);
		goto out_vvp;
	}

	cl_inode_fini_env->le_ctx.lc_cookie = 0x4;

	rc = ll_xattr_init();
	if (rc != 0)
		goto out_inode_fini_env;

	lustre_register_client_fill_super(ll_fill_super);
	lustre_register_kill_super_cb(ll_kill_super);
	lustre_register_client_process_config(ll_process_config);

	return 0;

out_inode_fini_env:
	cl_env_put(cl_inode_fini_env, &cl_inode_fini_refcheck);
out_vvp:
	vvp_global_fini();
out_sysfs:
	kset_unregister(llite_kset);
out_debugfs:
	debugfs_remove(llite_root);
out_cache:
	kmem_cache_destroy(ll_inode_cachep);
	kmem_cache_destroy(ll_file_data_slab);
	return rc;
}