예제 #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;
}
예제 #2
0
__u32
libcfs_str2net(const char *str)
{
        __u32  net;

        if (libcfs_str2net_internal(str, &net) != NULL)
                return net;

        return LNET_NIDNET(LNET_NID_ANY);
}
예제 #3
0
int lustre_lnet_del_net(char *nw, int seq_no, struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data data;
	__u32 net = LNET_NIDNET(LNET_NID_ANY);
	int rc = LUSTRE_CFG_RC_NO_ERR;
	char err_str[LNET_MAX_STR_LEN];

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

	if (nw == NULL) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"missing mandatory parameter\"");
		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;
	}

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

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

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

	return rc;
}
예제 #4
0
int
lnet_net_unique(__u32 net, struct list_head *nilist)
{
    struct list_head *tmp;
    lnet_ni_t	 *ni;

    list_for_each(tmp, nilist) {
        ni = list_entry(tmp, lnet_ni_t, ni_list);

        if (LNET_NIDNET(ni->ni_nid) == net)
            return 0;
    }
예제 #5
0
/*
 * range constructor
 *
 * \param	min		starting nid of the range
 * \param	max		ending nid of the range
 * \param	nodemap		nodemap that contains this range
 * \retval	lu_nid_range on success, NULL on failure
 */
struct lu_nid_range *range_create(lnet_nid_t start_nid, lnet_nid_t end_nid,
				  struct lu_nodemap *nodemap)
{
	struct lu_nid_range *range;

	if (LNET_NIDNET(start_nid) != LNET_NIDNET(end_nid) ||
	    LNET_NIDADDR(start_nid) > LNET_NIDADDR(end_nid))
		return NULL;

	OBD_ALLOC_PTR(range);
	if (range == NULL) {
		CERROR("cannot allocate lu_nid_range of size %zu bytes\n",
		       sizeof(*range));
		return NULL;
	}

	range->rn_id = atomic_inc_return(&range_highest_id);
	range->rn_nodemap = nodemap;
	interval_set(&range->rn_node, start_nid, end_nid);
	INIT_LIST_HEAD(&range->rn_list);

	return range;
}
예제 #6
0
파일: obd_mount.c 프로젝트: IDM350/linux
/** 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;
}
예제 #7
0
파일: acceptor.c 프로젝트: IDM350/linux
int
lnet_accept(socket_t *sock, __u32 magic)
{
	lnet_acceptor_connreq_t cr;
	__u32		   peer_ip;
	int		     peer_port;
	int		     rc;
	int		     flip;
	lnet_ni_t	      *ni;
	char		   *str;

	LASSERT(sizeof(cr) <= 16);	     /* not too big for the stack */

	rc = libcfs_sock_getaddr(sock, 1, &peer_ip, &peer_port);
	LASSERT(rc == 0);		      /* we succeeded before */

	if (!lnet_accept_magic(magic, LNET_PROTO_ACCEPTOR_MAGIC)) {

		if (lnet_accept_magic(magic, LNET_PROTO_MAGIC)) {
			/* future version compatibility!
			 * When LNET unifies protocols over all LNDs, the first
			 * thing sent will be a version query.  I send back
			 * LNET_PROTO_ACCEPTOR_MAGIC to tell her I'm "old" */

			memset(&cr, 0, sizeof(cr));
			cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC;
			cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;
			rc = libcfs_sock_write(sock, &cr, sizeof(cr),
					       accept_timeout);

			if (rc != 0)
				CERROR("Error sending magic+version in response to LNET magic from %pI4h: %d\n",
				       &peer_ip, rc);
			return -EPROTO;
		}

		if (magic == le32_to_cpu(LNET_PROTO_TCP_MAGIC))
			str = "'old' socknal/tcpnal";
		else if (lnet_accept_magic(magic, LNET_PROTO_RA_MAGIC))
			str = "'old' ranal";
		else
			str = "unrecognised";

		LCONSOLE_ERROR_MSG(0x11f, "Refusing connection from %pI4h magic %08x: %s acceptor protocol\n",
				   &peer_ip, magic, str);
		return -EPROTO;
	}

	flip = (magic != LNET_PROTO_ACCEPTOR_MAGIC);

	rc = libcfs_sock_read(sock, &cr.acr_version,
			      sizeof(cr.acr_version),
			      accept_timeout);
	if (rc != 0) {
		CERROR("Error %d reading connection request version from %pI4h\n",
			rc, &peer_ip);
		return -EIO;
	}

	if (flip)
		__swab32s(&cr.acr_version);

	if (cr.acr_version != LNET_PROTO_ACCEPTOR_VERSION) {
		/* future version compatibility!
		 * An acceptor-specific protocol rev will first send a version
		 * query.  I send back my current version to tell her I'm
		 * "old". */
		int peer_version = cr.acr_version;

		memset(&cr, 0, sizeof(cr));
		cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC;
		cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;

		rc = libcfs_sock_write(sock, &cr, sizeof(cr),
				       accept_timeout);

		if (rc != 0)
			CERROR("Error sending magic+version in response to version %d from %pI4h: %d\n",
			       peer_version, &peer_ip, rc);
		return -EPROTO;
	}

	rc = libcfs_sock_read(sock, &cr.acr_nid,
			      sizeof(cr) -
			      offsetof(lnet_acceptor_connreq_t, acr_nid),
			      accept_timeout);
	if (rc != 0) {
		CERROR("Error %d reading connection request from %pI4h\n",
			rc, &peer_ip);
		return -EIO;
	}

	if (flip)
		__swab64s(&cr.acr_nid);

	ni = lnet_net2ni(LNET_NIDNET(cr.acr_nid));
	if (ni == NULL ||	       /* no matching net */
	    ni->ni_nid != cr.acr_nid) { /* right NET, wrong NID! */
		if (ni != NULL)
			lnet_ni_decref(ni);
		LCONSOLE_ERROR_MSG(0x120, "Refusing connection from %pI4h for %s: No matching NI\n",
				   &peer_ip, libcfs_nid2str(cr.acr_nid));
		return -EPERM;
	}

	if (ni->ni_lnd->lnd_accept == NULL) {
		/* This catches a request for the loopback LND */
		lnet_ni_decref(ni);
		LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h for %s: NI doesn not accept IP connections\n",
				  &peer_ip, libcfs_nid2str(cr.acr_nid));
		return -EPERM;
	}

	CDEBUG(D_NET, "Accept %s from %pI4h\n",
	       libcfs_nid2str(cr.acr_nid), &peer_ip);

	rc = ni->ni_lnd->lnd_accept(ni, sock);

	lnet_ni_decref(ni);
	return rc;
}
예제 #8
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;
}
예제 #9
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;
}
예제 #10
0
파일: handlers.c 프로젝트: Lezval/lustre
/* All actions that we need after receiving hello on passive conn:
 * 1) Stash peer's nid, pid, incarnation and conn type
 * 2) Cope with easy case: conn[idx] is empty - just save conn there
 * 3) Resolve race:
 *    a) if our nid is higher - reply with CONN_NONE and make us zombie
 *    b) if peer's nid is higher - postpone race resolution till
 *       READY state
 * 4) Anyhow, send reply hello
*/
int
usocklnd_passiveconn_hellorecv(usock_conn_t *conn)
{
        ksock_hello_msg_t *hello = conn->uc_rx_hello;
        int                type;
        int                idx;
        int                rc;
        usock_peer_t      *peer;
        lnet_ni_t         *ni        = conn->uc_ni;
        __u32              peer_ip   = conn->uc_peer_ip;
        __u16              peer_port = conn->uc_peer_port;

        /* don't know parent peer yet and not zombie */
        LASSERT (conn->uc_peer == NULL &&
                 ni != NULL);

        /* don't know peer's nid and incarnation yet */
        if (peer_port > LNET_ACCEPTOR_MAX_RESERVED_PORT) {
                /* do not trust liblustre clients */
                conn->uc_peerid.pid = peer_port | LNET_PID_USERFLAG;
                conn->uc_peerid.nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid),
                                                 peer_ip);
                if (hello->kshm_ctype != SOCKLND_CONN_ANY) {
                        lnet_ni_decref(ni);
                        conn->uc_ni = NULL;
                        CERROR("Refusing to accept connection of type=%d from "
                               "userspace process %u.%u.%u.%u:%d\n", hello->kshm_ctype,
                               HIPQUAD(peer_ip), peer_port);
                        return -EINVAL;
                }
        } else {
                conn->uc_peerid.pid = hello->kshm_src_pid;
                conn->uc_peerid.nid = hello->kshm_src_nid;
        }
        conn->uc_type = type = usocklnd_invert_type(hello->kshm_ctype);

        rc = usocklnd_find_or_create_peer(ni, conn->uc_peerid, &peer);
        if (rc) {
                lnet_ni_decref(ni);
                conn->uc_ni = NULL;
                return rc;
        }

        peer->up_last_alive = cfs_time_current();

        idx = usocklnd_type2idx(conn->uc_type);

        /* safely check whether we're first */
        pthread_mutex_lock(&peer->up_lock);

        usocklnd_cleanup_stale_conns(peer, hello->kshm_src_incarnation, NULL);

        if (peer->up_conns[idx] == NULL) {
                peer->up_last_alive = cfs_time_current();
                conn->uc_peer = peer;
                conn->uc_ni = NULL;
                usocklnd_link_conn_to_peer(conn, peer, idx);
                usocklnd_conn_addref(conn);
        } else {
                usocklnd_peer_decref(peer);

                /* Resolve race in favour of higher NID */
                if (conn->uc_peerid.nid < conn->uc_ni->ni_nid) {
                        /* make us zombie */
                        conn->uc_ni = NULL;
                        type = SOCKLND_CONN_NONE;
                }

                /* if conn->uc_peerid.nid > conn->uc_ni->ni_nid,
                 * postpone race resolution till READY state
                 * (hopefully that conn[idx] will die because of
                 * incoming hello of CONN_NONE type) */
        }
        pthread_mutex_unlock(&peer->up_lock);

        /* allocate and initialize fake tx with hello */
        conn->uc_tx_hello = usocklnd_create_hello_tx(ni, type,
                                                     conn->uc_peerid.nid);
        if (conn->uc_ni == NULL)
                lnet_ni_decref(ni);

        if (conn->uc_tx_hello == NULL)
                return -ENOMEM;

        /* rc == 0 */
        pthread_mutex_lock(&conn->uc_lock);
        if (conn->uc_state == UC_DEAD)
                goto passive_hellorecv_done;

        conn->uc_state = UC_SENDING_HELLO;
        conn->uc_tx_deadline = cfs_time_shift(usock_tuns.ut_timeout);
        conn->uc_tx_flag = 1;
        rc = usocklnd_add_pollrequest(conn, POLL_SET_REQUEST, POLLOUT);

  passive_hellorecv_done:
        pthread_mutex_unlock(&conn->uc_lock);
        return rc;
}
예제 #11
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;
}
예제 #12
0
int lustre_lnet_show_net(char *nw, int detail, int seq_no,
			 struct cYAML **show_rc, struct cYAML **err_rc)
{
	char *buf;
	struct lnet_ioctl_config_lnd_tunables *lnd_cfg;
	struct lnet_ioctl_config_data *data;
	struct lnet_ioctl_net_config *net_config;
	__u32 net = LNET_NIDNET(LNET_NID_ANY);
	int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j;
	int l_errno = 0;
	struct cYAML *root = NULL, *tunables = NULL, *net_node = NULL,
		*interfaces = NULL, *item = NULL, *first_seq = NULL;
	int str_buf_len = LNET_MAX_SHOW_NUM_CPT * 2;
	char str_buf[str_buf_len];
	char *pos;
	char err_str[LNET_MAX_STR_LEN];
	bool exist = false;
	size_t buf_len;

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

	buf_len = sizeof(*data) + sizeof(*net_config) + sizeof(*lnd_cfg);
	buf = calloc(1, buf_len);
	if (buf == NULL)
		goto out;

	data = (struct lnet_ioctl_config_data *)buf;

	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;
		}
	}

	root = cYAML_create_object(NULL, NULL);
	if (root == NULL)
		goto out;

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

	for (i = 0;; i++) {
		pos = str_buf;

		memset(buf, 0, buf_len);

		LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
		/*
		 * set the ioc_len to the proper value since INIT assumes
		 * size of data
		 */
		data->cfg_hdr.ioc_len = buf_len;
		data->cfg_count = i;

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

		/* filter on provided data */
		if (net != LNET_NIDNET(LNET_NID_ANY) &&
		    net != LNET_NIDNET(data->cfg_nid))
			continue;

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

		net_config = (struct lnet_ioctl_net_config *)data->cfg_bulk;

		/* create the tree to be printed. */
		item = cYAML_create_seq_item(net_node);
		if (item == NULL)
			goto out;

		if (first_seq == NULL)
			first_seq = item;

		if (cYAML_create_string(item, "net",
					libcfs_net2str(
						LNET_NIDNET(data->cfg_nid)))
		    == NULL)
			goto out;

		if (cYAML_create_string(item, "nid",
					libcfs_nid2str(data->cfg_nid)) == NULL)
			goto out;

		if (cYAML_create_string(item, "status",
					(net_config->ni_status ==
					  LNET_NI_STATUS_UP) ?
					    "up" : "down") == NULL)
			goto out;

		/* don't add interfaces unless there is at least one
		 * interface */
		if (strlen(net_config->ni_interfaces[0]) > 0) {
			interfaces = cYAML_create_object(item, "interfaces");
			if (interfaces == NULL)
				goto out;

			for (j = 0; j < LNET_MAX_INTERFACES; j++) {
				if (lustre_interface_show_net(interfaces, j,
							      detail, data,
							      net_config) < 0)
					goto out;
			}
		}

		if (detail) {
			char *limit;

			tunables = cYAML_create_object(item, "tunables");
			if (tunables == NULL)
				goto out;

			if (cYAML_create_number(tunables, "peer_timeout",
						data->cfg_config_u.cfg_net.
						net_peer_timeout) == NULL)
				goto out;

			if (cYAML_create_number(tunables, "peer_credits",
						data->cfg_config_u.cfg_net.
						net_peer_tx_credits) == NULL)
				goto out;

			if (cYAML_create_number(tunables,
						"peer_buffer_credits",
						data->cfg_config_u.cfg_net.
						net_peer_rtr_credits) == NULL)
				goto out;

			if (cYAML_create_number(tunables, "credits",
						data->cfg_config_u.cfg_net.
						net_max_tx_credits) == NULL)
				goto out;

			/* out put the CPTs in the format: "[x,x,x,...]" */
			limit = str_buf + str_buf_len - 3;
			pos += snprintf(pos, limit - pos, "\"[");
			for (j = 0 ; data->cfg_ncpts > 1 &&
				j < data->cfg_ncpts &&
				pos < limit; j++) {
				pos += snprintf(pos, limit - pos,
						"%d", net_config->ni_cpts[j]);
				if ((j + 1) < data->cfg_ncpts)
					pos += snprintf(pos, limit - pos, ",");
			}
			pos += snprintf(pos, 3, "]\"");

			if (data->cfg_ncpts > 1 &&
			    cYAML_create_string(tunables, "CPT",
						str_buf) == NULL)
				goto out;
		}
	}

	/* Print out the net information only if 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 networks: %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 net node, if one doesn't exist
		 * then insert one.  Otherwise add to the one there
		 */
		show_node = cYAML_get_object_item(*show_rc, "net");
		if (show_node != NULL && cYAML_is_sequence(show_node)) {
			cYAML_insert_child(show_node, first_seq);
			free(net_node);
			free(root);
		} else if (show_node == NULL) {
			cYAML_insert_sibling((*show_rc)->cy_child,
						net_node);
			free(root);
		} else {
			cYAML_free_tree(root);
		}
	} else {
		*show_rc = root;
	}

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

	return rc;
}
예제 #13
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;
}
예제 #14
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;
}
예제 #15
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);
예제 #16
0
파일: super25.c 프로젝트: asmalldev/linux
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;
}