config.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,390 行 · 第 1/3 页

C
1,390
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  Copyright (c) 2005 Cluster File Systems, Inc. * *   This file is part of Lustre, http://www.sf.net/projects/lustre/ * *   Lustre is free software; you can redistribute it and/or *   modify it under the terms of version 2 of the GNU General Public *   License as published by the Free Software Foundation. * *   Lustre is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with Lustre; if not, write to the Free Software *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#define DEBUG_SUBSYSTEM S_LNET#include <lnet/lib-lnet.h>typedef struct {                                /* tmp struct for parsing routes */	struct list_head   ltb_list;		/* stash on lists */	int                ltb_size;		/* allocated size */	char               ltb_text[0];		/* text buffer */} lnet_text_buf_t;static int lnet_tbnob = 0;			/* track text buf allocation */#define LNET_MAX_TEXTBUF_NOB     (64<<10)	/* bound allocation */#define LNET_SINGLE_TEXTBUF_NOB  (4<<10)typedef struct {        struct list_head   lre_list;            /* stash in a list */        int                lre_min;             /* min value */        int                lre_max;             /* max value */        int                lre_stride;          /* stride */} lnet_range_expr_t;static int lnet_re_alloc = 0;                   /* track expr allocation */void lnet_syntax(char *name, char *str, int offset, int width){        static char dots[LNET_SINGLE_TEXTBUF_NOB];        static char dashes[LNET_SINGLE_TEXTBUF_NOB];                memset(dots, '.', sizeof(dots));        dots[sizeof(dots)-1] = 0;        memset(dashes, '-', sizeof(dashes));        dashes[sizeof(dashes)-1] = 0;        	LCONSOLE_ERROR_MSG(0x10f, "Error parsing '%s=\"%s\"'\n", name, str);	LCONSOLE_ERROR_MSG(0x110, "here...........%.*s..%.*s|%.*s|\n",                            (int)strlen(name), dots, offset, dots,                            (width < 1) ? 0 : width - 1, dashes);}int lnet_issep (char c){	switch (c) {	case '\n':	case '\r':	case ';':		return 1;	default:		return 0;	}}intlnet_iswhite (char c){	switch (c) {	case ' ':	case '\t':	case '\n':	case '\r':		return 1;	default:		return 0;	}}char *lnet_trimwhite(char *str){	char *end;		while (lnet_iswhite(*str))		str++;		end = str + strlen(str);	while (end > str) {		if (!lnet_iswhite(end[-1]))			break;		end--;	}	*end = 0;	return str;}intlnet_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;        }                return 1;}lnet_ni_t *lnet_new_ni(__u32 net, struct list_head *nilist){        lnet_ni_t *ni;        if (!lnet_net_unique(net, nilist)) {                LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n",                                   libcfs_net2str(net));                return NULL;        }                LIBCFS_ALLOC(ni, sizeof(*ni));        if (ni == NULL) {                CERROR("Out of memory creating network %s\n",                       libcfs_net2str(net));                return NULL;        }                /* zero counters/flags, NULL pointers... */        memset(ni, 0, sizeof(*ni));        /* LND will fill in the address part of the NID */        ni->ni_nid = LNET_MKNID(net, 0);        CFS_INIT_LIST_HEAD(&ni->ni_txq);        list_add_tail(&ni->ni_list, nilist);        return ni;}intlnet_parse_networks(struct list_head *nilist, char *networks){	int        tokensize = strlen(networks) + 1;        char      *tokens;        char      *str;        lnet_ni_t *ni;        __u32      net;        int        nnets = 0;	if (strlen(networks) > LNET_SINGLE_TEXTBUF_NOB) {		/* _WAY_ conservative */		LCONSOLE_ERROR_MSG(0x112, "Can't parse networks: string too "                                   "long\n");		return -EINVAL;	}        LIBCFS_ALLOC(tokens, tokensize);        if (tokens == NULL) {                CERROR("Can't allocate net tokens\n");		return -ENOMEM;        }        the_lnet.ln_network_tokens = tokens;        the_lnet.ln_network_tokens_nob = tokensize;        memcpy (tokens, networks, tokensize);	str = tokens;                /* Add in the loopback network */        ni = lnet_new_ni(LNET_MKNET(LOLND, 0), nilist);        if (ni == NULL)                goto failed;                while (str != NULL && *str != 0) {                char      *comma = strchr(str, ',');                char      *bracket = strchr(str, '(');                int        niface;		char      *iface;                /* NB we don't check interface conflicts here; it's the LNDs                 * responsibility (if it cares at all) */                if (bracket == NULL ||		    (comma != NULL && comma < bracket)) {                        /* no interface list specified */			if (comma != NULL)				*comma++ = 0;			net = libcfs_str2net(lnet_trimwhite(str));						if (net == LNET_NIDNET(LNET_NID_ANY)) {                                lnet_syntax("networks", networks,                                             str - tokens, strlen(str));                                LCONSOLE_ERROR_MSG(0x113, "Unrecognised network"                                                   " type\n");                                goto failed;                        }                        if (LNET_NETTYP(net) != LOLND && /* loopback is implicit */                            lnet_new_ni(net, nilist) == NULL)                                goto failed;			str = comma;			continue;		}		*bracket = 0;		net = libcfs_str2net(lnet_trimwhite(str));		if (net == LNET_NIDNET(LNET_NID_ANY)) {                        lnet_syntax("networks", networks,                                    str - tokens, strlen(str));                        goto failed;                }                 if (nnets > 0 &&                    the_lnet.ln_ptlcompat > 0) {                        LCONSOLE_ERROR_MSG(0x114, "Only 1 network supported when"                                           " 'portals_compatible' is set\n");                        goto failed;                }                nnets++;                ni = lnet_new_ni(net, nilist);                if (ni == NULL)                        goto failed;                niface = 0;		iface = bracket + 1;		bracket = strchr(iface, ')');		if (bracket == NULL) {                        lnet_syntax("networks", networks,                                    iface - tokens, strlen(iface));                        goto failed;		}		*bracket = 0;		do {			comma = strchr(iface, ',');			if (comma != NULL)				*comma++ = 0;						iface = lnet_trimwhite(iface);			if (*iface == 0) {                                lnet_syntax("networks", networks,                                             iface - tokens, strlen(iface));                                goto failed;                        }                        if (niface == LNET_MAX_INTERFACES) {                                LCONSOLE_ERROR_MSG(0x115, "Too many interfaces "                                                   "for net %s\n",                                                   libcfs_net2str(net));                                goto failed;                        }                        ni->ni_interfaces[niface++] = iface;			iface = comma;		} while (iface != NULL);		str = bracket + 1;		comma = strchr(bracket + 1, ',');		if (comma != NULL) {			*comma = 0;			str = lnet_trimwhite(str);			if (*str != 0) {                                lnet_syntax("networks", networks,                                            str - tokens, strlen(str));                                goto failed;                        }			str = comma + 1;			continue;		}				str = lnet_trimwhite(str);		if (*str != 0) {                        lnet_syntax("networks", networks,                                    str - tokens, strlen(str));                        goto failed;                }	}        LASSERT (!list_empty(nilist));        return 0; failed:        while (!list_empty(nilist)) {                ni = list_entry(nilist->next, lnet_ni_t, ni_list);                                list_del(&ni->ni_list);                LIBCFS_FREE(ni, sizeof(*ni));        }	LIBCFS_FREE(tokens, tokensize);        the_lnet.ln_network_tokens = NULL;        return -EINVAL;}lnet_text_buf_t *lnet_new_text_buf (int str_len) {	lnet_text_buf_t *ltb;	int              nob;        /* NB allocate space for the terminating 0 */	nob = offsetof(lnet_text_buf_t, ltb_text[str_len + 1]);	if (nob > LNET_SINGLE_TEXTBUF_NOB) {		/* _way_ conservative for "route net gateway..." */		CERROR("text buffer too big\n");		return NULL;	}	if (lnet_tbnob + nob > LNET_MAX_TEXTBUF_NOB) {		CERROR("Too many text buffers\n");		return NULL;	}		LIBCFS_ALLOC(ltb, nob);	if (ltb == NULL)		return NULL;	ltb->ltb_size = nob;        ltb->ltb_text[0] = 0;	lnet_tbnob += nob;	return ltb;}voidlnet_free_text_buf (lnet_text_buf_t *ltb){	lnet_tbnob -= ltb->ltb_size;	LIBCFS_FREE(ltb, ltb->ltb_size);}voidlnet_free_text_bufs(struct list_head *tbs){	lnet_text_buf_t  *ltb;		while (!list_empty(tbs)) {		ltb = list_entry(tbs->next, lnet_text_buf_t, ltb_list);				list_del(&ltb->ltb_list);		lnet_free_text_buf(ltb);	}}voidlnet_print_text_bufs(struct list_head *tbs){	struct list_head  *tmp;	lnet_text_buf_t   *ltb;	list_for_each (tmp, tbs) {		ltb = list_entry(tmp, lnet_text_buf_t, ltb_list);		CDEBUG(D_WARNING, "%s\n", ltb->ltb_text);	}	CDEBUG(D_WARNING, "%d allocated\n", lnet_tbnob);}intlnet_str2tbs_sep (struct list_head *tbs, char *str) {	struct list_head  pending;	char             *sep;	int               nob;        int               i;	lnet_text_buf_t  *ltb;	CFS_INIT_LIST_HEAD(&pending);	/* Split 'str' into separate commands */	for (;;) {                /* skip leading whitespace */                while (lnet_iswhite(*str))                        str++;                		/* scan for separator or comment */		for (sep = str; *sep != 0; sep++)			if (lnet_issep(*sep) || *sep == '#')				break;		nob = sep - str;		if (nob > 0) {			ltb = lnet_new_text_buf(nob);			if (ltb == NULL) {				lnet_free_text_bufs(&pending);				return -1;			}			                        for (i = 0; i < nob; i++)                                if (lnet_iswhite(str[i]))                                        ltb->ltb_text[i] = ' ';                                else                                        ltb->ltb_text[i] = str[i];			ltb->ltb_text[nob] = 0;			list_add_tail(&ltb->ltb_list, &pending);		}		if (*sep == '#') {			/* scan for separator */			do {				sep++;			} while (*sep != 0 && !lnet_issep(*sep));		}				if (*sep == 0)			break;		str = sep + 1;	}	list_splice(&pending, tbs->prev);	return 0;}intlnet_expand1tb (struct list_head *list, 	       char *str, char *sep1, char *sep2, 	       char *item, int itemlen){	int              len1 = sep1 - str;	int              len2 = strlen(sep2 + 1);	lnet_text_buf_t *ltb;	LASSERT (*sep1 == '[');	LASSERT (*sep2 == ']');	ltb = lnet_new_text_buf(len1 + itemlen + len2);	if (ltb == NULL)		return -ENOMEM;		memcpy(ltb->ltb_text, str, len1);	memcpy(&ltb->ltb_text[len1], item, itemlen);	memcpy(&ltb->ltb_text[len1+itemlen], sep2 + 1, len2);	ltb->ltb_text[len1 + itemlen + len2] = 0;		list_add_tail(&ltb->ltb_list, list);	return 0;}intlnet_str2tbs_expand (struct list_head *tbs, char *str){	char              num[16];	struct list_head  pending;	char             *sep;	char             *sep2;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?