📄 nidstrings.c
字号:
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Copyright (C) 2002 Cluster File Systems, Inc. * Author: Phil Schwan <phil@clusterfs.com> * * This file is part of Lustre, http://www.lustre.org. * * 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. */#ifndef EXPORT_SYMTAB# define EXPORT_SYMTAB#endif#define DEBUG_SUBSYSTEM S_LNET#include <lnet/lnet.h>#include <libcfs/kp30.h>#ifndef __KERNEL__#ifdef HAVE_GETHOSTBYNAME# include <netdb.h>#endif#endif/* CAVEAT VENDITOR! Keep the canonical string representation of nets/nids * consistent in all conversion functions. Some code fragments are copied * around for the sake of clarity... *//* CAVEAT EMPTOR! Racey temporary buffer allocation! * Choose the number of nidstrings to support the MAXIMUM expected number of * concurrent users. If there are more, the returned string will be volatile. * NB this number must allow for a process to be descheduled for a timeslice * between getting its string and using it. */#define LNET_NIDSTR_COUNT 128 /* # of nidstrings */#define LNET_NIDSTR_SIZE 32 /* size of each one (see below for usage) */static char libcfs_nidstrings[LNET_NIDSTR_COUNT][LNET_NIDSTR_SIZE];static int libcfs_nidstring_idx = 0;#ifdef __KERNEL__static spinlock_t libcfs_nidstring_lock;void libcfs_init_nidstrings (void){ spin_lock_init(&libcfs_nidstring_lock);}# define NIDSTR_LOCK(f) spin_lock_irqsave(&libcfs_nidstring_lock, f)# define NIDSTR_UNLOCK(f) spin_unlock_irqrestore(&libcfs_nidstring_lock, f)#else# define NIDSTR_LOCK(f) (f=0) /* avoid unused var warnings */# define NIDSTR_UNLOCK(f) (f=0)#endifstatic char *libcfs_next_nidstring (void){ char *str; unsigned long flags; NIDSTR_LOCK(flags); str = libcfs_nidstrings[libcfs_nidstring_idx++]; if (libcfs_nidstring_idx == sizeof(libcfs_nidstrings)/sizeof(libcfs_nidstrings[0])) libcfs_nidstring_idx = 0; NIDSTR_UNLOCK(flags); return str;}static int libcfs_lo_str2addr(const char *str, int nob, __u32 *addr);static void libcfs_ip_addr2str(__u32 addr, char *str);static int libcfs_ip_str2addr(const char *str, int nob, __u32 *addr);static void libcfs_decnum_addr2str(__u32 addr, char *str);static void libcfs_hexnum_addr2str(__u32 addr, char *str);static int libcfs_num_str2addr(const char *str, int nob, __u32 *addr);struct netstrfns { int nf_type; char *nf_name; char *nf_modname; void (*nf_addr2str)(__u32 addr, char *str); int (*nf_str2addr)(const char *str, int nob, __u32 *addr);};static struct netstrfns libcfs_netstrfns[] = { {/* .nf_type */ LOLND, /* .nf_name */ "lo", /* .nf_modname */ "klolnd", /* .nf_addr2str */ libcfs_decnum_addr2str, /* .nf_str2addr */ libcfs_lo_str2addr}, {/* .nf_type */ SOCKLND, /* .nf_name */ "tcp", /* .nf_modname */ "ksocklnd", /* .nf_addr2str */ libcfs_ip_addr2str, /* .nf_str2addr */ libcfs_ip_str2addr}, {/* .nf_type */ O2IBLND, /* .nf_name */ "o2ib", /* .nf_modname */ "ko2iblnd", /* .nf_addr2str */ libcfs_ip_addr2str, /* .nf_str2addr */ libcfs_ip_str2addr}, {/* .nf_type */ CIBLND, /* .nf_name */ "cib", /* .nf_modname */ "kciblnd", /* .nf_addr2str */ libcfs_ip_addr2str, /* .nf_str2addr */ libcfs_ip_str2addr}, {/* .nf_type */ OPENIBLND, /* .nf_name */ "openib", /* .nf_modname */ "kopeniblnd", /* .nf_addr2str */ libcfs_ip_addr2str, /* .nf_str2addr */ libcfs_ip_str2addr}, {/* .nf_type */ IIBLND, /* .nf_name */ "iib", /* .nf_modname */ "kiiblnd", /* .nf_addr2str */ libcfs_ip_addr2str, /* .nf_str2addr */ libcfs_ip_str2addr}, {/* .nf_type */ VIBLND, /* .nf_name */ "vib", /* .nf_modname */ "kviblnd", /* .nf_addr2str */ libcfs_ip_addr2str, /* .nf_str2addr */ libcfs_ip_str2addr}, {/* .nf_type */ RALND, /* .nf_name */ "ra", /* .nf_modname */ "kralnd", /* .nf_addr2str */ libcfs_ip_addr2str, /* .nf_str2addr */ libcfs_ip_str2addr}, {/* .nf_type */ QSWLND, /* .nf_name */ "elan", /* .nf_modname */ "kqswlnd", /* .nf_addr2str */ libcfs_decnum_addr2str, /* .nf_str2addr */ libcfs_num_str2addr}, {/* .nf_type */ GMLND, /* .nf_name */ "gm", /* .nf_modname */ "kgmlnd", /* .nf_addr2str */ libcfs_hexnum_addr2str, /* .nf_str2addr */ libcfs_num_str2addr}, {/* .nf_type */ MXLND, /* .nf_name */ "mx", /* .nf_modname */ "kmxlnd", /* .nf_addr2str */ libcfs_ip_addr2str, /* .nf_str2addr */ libcfs_ip_str2addr}, {/* .nf_type */ PTLLND, /* .nf_name */ "ptl", /* .nf_modname */ "kptllnd", /* .nf_addr2str */ libcfs_decnum_addr2str, /* .nf_str2addr */ libcfs_num_str2addr}, /* placeholder for net0 alias. It MUST BE THE LAST ENTRY */ {/* .nf_type */ -1},};const int libcfs_nnetstrfns = sizeof(libcfs_netstrfns)/sizeof(libcfs_netstrfns[0]);intlibcfs_lo_str2addr(const char *str, int nob, __u32 *addr){ *addr = 0; return 1;}voidlibcfs_ip_addr2str(__u32 addr, char *str){#if 0 /* never lookup */#if !defined(__KERNEL__) && defined HAVE_GETHOSTBYNAME __u32 netip = htonl(addr); struct hostent *he = gethostbyaddr(&netip, sizeof(netip), AF_INET); if (he != NULL) { snprintf(str, LNET_NIDSTR_SIZE, "%s", he->h_name); return; }#endif#endif snprintf(str, LNET_NIDSTR_SIZE, "%u.%u.%u.%u", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);}/* CAVEAT EMPTOR XscanfX * I use "%n" at the end of a sscanf format to detect trailing junk. However * sscanf may return immediately if it sees the terminating '0' in a string, so * I initialise the %n variable to the expected length. If sscanf sets it; * fine, if it doesn't, then the scan ended at the end of the string, which is * fine too :) */intlibcfs_ip_str2addr(const char *str, int nob, __u32 *addr){ int a; int b; int c; int d; int n = nob; /* XscanfX */ /* numeric IP? */ if (sscanf(str, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n) >= 4 && n == nob && (a & ~0xff) == 0 && (b & ~0xff) == 0 && (c & ~0xff) == 0 && (d & ~0xff) == 0) { *addr = ((a<<24)|(b<<16)|(c<<8)|d); return 1; }#if !defined(__KERNEL__) && defined HAVE_GETHOSTBYNAME /* known hostname? */ if (('a' <= str[0] && str[0] <= 'z') || ('A' <= str[0] && str[0] <= 'Z')) { char *tmp; LIBCFS_ALLOC(tmp, nob + 1); if (tmp != NULL) { struct hostent *he; memcpy(tmp, str, nob); tmp[nob] = 0; he = gethostbyname(tmp); LIBCFS_FREE(tmp, nob); if (he != NULL) { __u32 ip = *(__u32 *)he->h_addr; *addr = ntohl(ip); return 1; } } }#endif return 0;}voidlibcfs_decnum_addr2str(__u32 addr, char *str){ snprintf(str, LNET_NIDSTR_SIZE, "%u", addr);}voidlibcfs_hexnum_addr2str(__u32 addr, char *str){ snprintf(str, LNET_NIDSTR_SIZE, "0x%x", addr);}intlibcfs_num_str2addr(const char *str, int nob, __u32 *addr){ int n; n = nob; if (sscanf(str, "0x%x%n", addr, &n) >= 1 && n == nob) return 1; n = nob; if (sscanf(str, "0X%x%n", addr, &n) >= 1 && n == nob)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -