support get local mac addresses
parent
5d130c1608
commit
1c6a73d4f3
3
HISTORY
3
HISTORY
|
|
@ -1,8 +1,9 @@
|
|||
|
||||
Version 1.24 2015-12-30
|
||||
Version 1.24 2016-01-12
|
||||
* php extension compiled on PHP 7
|
||||
* add skiplist which support stable sort
|
||||
* make.sh: use sed to replace perl
|
||||
* support get local mac addresses
|
||||
|
||||
Version 1.23 2015-11-16
|
||||
* sched_thread.c: task can execute in a new thread
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ int fast_mblock_manager_stat_print(const bool hide_empty)
|
|||
}
|
||||
}
|
||||
|
||||
logInfo("%20s %12d %8d %12d %10d %10d %14d %12d %11.2f%%", pStat->name,
|
||||
logInfo("%20s %12d %8d %12"PRId64" %10d %10d %14d %12d %11.2f%%", pStat->name,
|
||||
pStat->element_size, pStat->instance_count, amem,
|
||||
pStat->trunk_total_count, pStat->trunk_used_count,
|
||||
pStat->element_total_count, pStat->element_used_count,
|
||||
|
|
|
|||
187
src/sockopt.c
187
src/sockopt.c
|
|
@ -22,7 +22,6 @@
|
|||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#if defined(OS_LINUX) || defined(OS_FREEBSD)
|
||||
#include <ifaddrs.h>
|
||||
|
|
@ -43,6 +42,9 @@
|
|||
#else
|
||||
#ifdef OS_FREEBSD
|
||||
#include <sys/uio.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <net/route.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
@ -1801,3 +1803,186 @@ int gethostaddrs(char **if_alias_prefixes, const int prefix_count, \
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(OS_LINUX) || defined(OS_FREEBSD)
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
static int getifmac(FastIFConfig *config)
|
||||
{
|
||||
int sockfd;
|
||||
struct ifreq req[1];
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd < 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"unable to create socket, "
|
||||
"errno: %d, error info: %s",
|
||||
__LINE__, errno, STRERROR(errno));
|
||||
return errno != 0 ? errno : EPERM;
|
||||
}
|
||||
|
||||
memset(req, 0, sizeof(struct ifreq));
|
||||
strcpy(req->ifr_name, config->name);
|
||||
if (ioctl(sockfd, SIOCGIFHWADDR, req) < 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"ioctl error, errno: %d, error info: %s",
|
||||
__LINE__, errno, STRERROR(errno));
|
||||
close(sockfd);
|
||||
return errno != 0 ? errno : EPERM;
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
snprintf(config->mac, sizeof(config->mac),
|
||||
"%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
req->ifr_hwaddr.sa_data[0] & 0xff,
|
||||
req->ifr_hwaddr.sa_data[1] & 0xff,
|
||||
req->ifr_hwaddr.sa_data[2] & 0xff,
|
||||
req->ifr_hwaddr.sa_data[3] & 0xff,
|
||||
req->ifr_hwaddr.sa_data[4] & 0xff,
|
||||
req->ifr_hwaddr.sa_data[5] & 0xff);
|
||||
return 0;
|
||||
}
|
||||
#else //FreeBSD
|
||||
static int getifmac(FastIFConfig *config)
|
||||
{
|
||||
int mib[6];
|
||||
size_t len;
|
||||
char buf[256];
|
||||
unsigned char *ptr;
|
||||
struct if_msghdr *ifm;
|
||||
struct sockaddr_dl *sdl;
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = AF_ROUTE;
|
||||
mib[2] = 0;
|
||||
mib[3] = AF_LINK;
|
||||
mib[4] = NET_RT_IFLIST;
|
||||
|
||||
if ((mib[5] = if_nametoindex(config->name)) == 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"call if_nametoindex fail, "
|
||||
"errno: %d, error info: %s",
|
||||
__LINE__, errno, STRERROR(errno));
|
||||
return errno != 0 ? errno : EPERM;
|
||||
}
|
||||
|
||||
len = sizeof(buf);
|
||||
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"call sysctl fail, "
|
||||
"errno: %d, error info: %s",
|
||||
__LINE__, errno, STRERROR(errno));
|
||||
return errno != 0 ? errno : EPERM;
|
||||
}
|
||||
|
||||
ifm = (struct if_msghdr *)buf;
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
ptr = (unsigned char *)LLADDR(sdl);
|
||||
snprintf(config->mac, sizeof(config->mac),
|
||||
"%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
*ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int getifconfigs(FastIFConfig *if_configs, const int max_count, int *count)
|
||||
{
|
||||
struct ifaddrs *ifc;
|
||||
struct ifaddrs *ifc1;
|
||||
FastIFConfig *config;
|
||||
char *buff;
|
||||
int buff_size;
|
||||
int i;
|
||||
|
||||
*count = 0;
|
||||
memset(if_configs, 0, sizeof(FastIFConfig) * max_count);
|
||||
if (0 != getifaddrs(&ifc))
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"call getifaddrs fail, " \
|
||||
"errno: %d, error info: %s", \
|
||||
__LINE__, errno, STRERROR(errno));
|
||||
return errno != 0 ? errno : EMFILE;
|
||||
}
|
||||
|
||||
ifc1 = ifc;
|
||||
while (NULL != ifc)
|
||||
{
|
||||
struct sockaddr *s;
|
||||
s = ifc->ifa_addr;
|
||||
if (NULL != s)
|
||||
{
|
||||
if (AF_INET == s->sa_family || AF_INET6 == s->sa_family)
|
||||
{
|
||||
for (i=0; i<*count; i++)
|
||||
{
|
||||
if (strcmp(if_configs[i].name, ifc->ifa_name) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
config = if_configs + i;
|
||||
if (i == *count) //not found
|
||||
{
|
||||
if (max_count <= *count)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "\
|
||||
"max_count: %d < iterface count: %d", \
|
||||
__LINE__, max_count, *count);
|
||||
freeifaddrs(ifc1);
|
||||
return ENOSPC;
|
||||
}
|
||||
|
||||
sprintf(config->name, "%s", ifc->ifa_name);
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
if (AF_INET == s->sa_family)
|
||||
{
|
||||
buff = config->ipv4;
|
||||
buff_size = sizeof(config->ipv4);
|
||||
}
|
||||
else
|
||||
{
|
||||
buff = config->ipv6;
|
||||
buff_size = sizeof(config->ipv6);
|
||||
}
|
||||
|
||||
if (inet_ntop(s->sa_family, &((struct sockaddr_in *)s)->
|
||||
sin_addr, buff, buff_size) == NULL)
|
||||
{
|
||||
logWarning("file: "__FILE__", line: %d, " \
|
||||
"call inet_ntop fail, " \
|
||||
"errno: %d, error info: %s", \
|
||||
__LINE__, errno, STRERROR(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ifc = ifc->ifa_next;
|
||||
}
|
||||
|
||||
freeifaddrs(ifc1);
|
||||
|
||||
printf ("count: %d\n", *count);
|
||||
for (i=0; i<*count; i++)
|
||||
{
|
||||
getifmac(if_configs + i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int getifconfigs(FastIFConfig *if_configs, const int max_count, int *count)
|
||||
{
|
||||
*count = 0;
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,18 @@
|
|||
#ifndef _SOCKETOPT_H_
|
||||
#define _SOCKETOPT_H_
|
||||
|
||||
#include <net/if.h>
|
||||
#include "common_define.h"
|
||||
|
||||
#define FAST_WRITE_BUFF_SIZE 256 * 1024
|
||||
|
||||
typedef struct fast_if_config {
|
||||
char name[IF_NAMESIZE];
|
||||
char mac[32];
|
||||
char ipv4[IP_ADDRESS_SIZE];
|
||||
char ipv6[48];
|
||||
} FastIFConfig;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
@ -317,16 +325,6 @@ int tcpdiscard(int sock, const int bytes, const int timeout, \
|
|||
int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
|
||||
const int max_count, int *count);
|
||||
|
||||
/** get local host ip addresses
|
||||
* parameters:
|
||||
* ip_addrs: store the ip addresses
|
||||
* max_count: max ip address (max ip_addrs elements)
|
||||
* count: store the ip address count
|
||||
* return: error no, 0 success, != 0 fail
|
||||
*/
|
||||
int getlocaladdrs1(char ip_addrs[][IP_ADDRESS_SIZE], \
|
||||
const int max_count, int *count);
|
||||
|
||||
/** get local host ip addresses by if alias prefix
|
||||
* parameters:
|
||||
* if_alias_prefixes: if alias prefixes, such as eth, bond etc.
|
||||
|
|
@ -339,6 +337,15 @@ int getlocaladdrs1(char ip_addrs[][IP_ADDRESS_SIZE], \
|
|||
int gethostaddrs(char **if_alias_prefixes, const int prefix_count, \
|
||||
char ip_addrs[][IP_ADDRESS_SIZE], const int max_count, int *count);
|
||||
|
||||
/** get local if configs
|
||||
* parameters:
|
||||
* if_configs: store the if configs
|
||||
* max_count: max ip address (max ip_addrs elements)
|
||||
* count: store the ip address count
|
||||
* return: error no, 0 success, != 0 fail
|
||||
*/
|
||||
int getifconfigs(FastIFConfig *if_configs, const int max_count, int *count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ COMPILE = $(CC) -g -O1 -Wall -D_FILE_OFFSET_BITS=64 -g -DDEBUG_FLAG
|
|||
INC_PATH = -I/usr/include/fastcommon
|
||||
LIB_PATH = -lfastcommon
|
||||
|
||||
ALL_PRGS = test_allocator test_skiplist test_multi_skiplist
|
||||
ALL_PRGS = test_allocator test_skiplist test_multi_skiplist test_mblock
|
||||
|
||||
all: $(ALL_PRGS)
|
||||
.c:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/time.h>
|
||||
#include "logger.h"
|
||||
#include "shared_func.h"
|
||||
#include "sched_thread.h"
|
||||
#include "ini_file_reader.h"
|
||||
#include "fast_mblock.h"
|
||||
#include "sockopt.h"
|
||||
|
||||
struct my_struct {
|
||||
struct fast_mblock_man *mblock;
|
||||
void *obj;
|
||||
};
|
||||
|
||||
static int test_delay(void *args)
|
||||
{
|
||||
struct my_struct *my;
|
||||
my = (struct my_struct *)args;
|
||||
fast_mblock_free_object(my->mblock, my->obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int result;
|
||||
int64_t start_time;
|
||||
int64_t end_time;
|
||||
char *filename;
|
||||
IniContext iniContext;
|
||||
int64_t mem_size;
|
||||
struct fast_mblock_man mblock1;
|
||||
struct fast_mblock_man mblock2;
|
||||
struct my_struct *objs;
|
||||
void *obj1;
|
||||
void *obj2;
|
||||
int reclaim_target;
|
||||
int reclaim_count;
|
||||
int i;
|
||||
int count;
|
||||
pthread_t schedule_tid;
|
||||
ScheduleArray scheduleArray;
|
||||
ScheduleEntry scheduleEntries[1];
|
||||
volatile bool continue_flag = true;
|
||||
FastIFConfig if_configs[32];
|
||||
|
||||
if (argc > 1) {
|
||||
filename = argv[1];
|
||||
} else {
|
||||
filename = "/etc/mc/worker.conf";
|
||||
}
|
||||
|
||||
start_time = get_current_time_ms();
|
||||
srand(time(NULL));
|
||||
log_init();
|
||||
g_log_context.log_level = LOG_DEBUG;
|
||||
if ((result=iniLoadFromFile(filename, &iniContext)) != 0) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"load conf file \"%s\" fail, ret code: %d",
|
||||
__LINE__, filename, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
getifconfigs(if_configs, 32, &count);
|
||||
for (i=0; i<count; i++) {
|
||||
printf("%s ipv4: %s, ipv6: %s, mac: %s\n",
|
||||
if_configs[i].name, if_configs[i].ipv4,
|
||||
if_configs[i].ipv6, if_configs[i].mac);
|
||||
}
|
||||
|
||||
//iniPrintItems(&iniContext);
|
||||
iniFreeContext(&iniContext);
|
||||
|
||||
sched_enable_delay_task();
|
||||
scheduleArray.entries = scheduleEntries;
|
||||
scheduleArray.count = 0;
|
||||
sched_start(&scheduleArray, &schedule_tid,
|
||||
64 * 1024, (bool * volatile)&continue_flag);
|
||||
|
||||
if (get_sys_total_mem_size(&mem_size) == 0) {
|
||||
printf("total memory size: %"PRId64" MB\n", mem_size / (1024 * 1024));
|
||||
}
|
||||
printf("cpu count: %d\n", get_sys_cpu_count());
|
||||
|
||||
end_time = get_current_time_ms();
|
||||
logInfo("time used: %d ms", (int)(end_time - start_time));
|
||||
|
||||
fast_mblock_manager_init();
|
||||
|
||||
fast_mblock_init_ex2(&mblock1, "mblock1", 1024, 128, NULL, false, NULL, NULL, NULL);
|
||||
fast_mblock_init_ex2(&mblock2, "mblock2", 1024, 100, NULL, false, NULL, NULL, NULL);
|
||||
|
||||
count = 2048;
|
||||
objs = (struct my_struct *)malloc(sizeof(struct my_struct) * count);
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
int delay;
|
||||
|
||||
delay = (30L * rand()) / RAND_MAX;
|
||||
|
||||
objs[i].mblock = &mblock1;
|
||||
objs[i].obj = fast_mblock_alloc_object(&mblock1);
|
||||
sched_add_delay_task(test_delay, objs + i, delay, false);
|
||||
}
|
||||
|
||||
/*
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
fast_mblock_free_object(&mblock1, objs[i]);
|
||||
}
|
||||
*/
|
||||
|
||||
obj1 = fast_mblock_alloc_object(&mblock1);
|
||||
obj2 = fast_mblock_alloc_object(&mblock1);
|
||||
fast_mblock_free_object(&mblock1, obj1);
|
||||
//fast_mblock_delay_free_object(&mblock1, obj2, 10);
|
||||
fast_mblock_free_object(&mblock1, obj2);
|
||||
|
||||
obj1 = fast_mblock_alloc_object(&mblock2);
|
||||
obj2 = fast_mblock_alloc_object(&mblock2);
|
||||
fast_mblock_delay_free_object(&mblock2, obj1, 20);
|
||||
fast_mblock_free_object(&mblock2, obj2);
|
||||
fast_mblock_manager_stat_print(false);
|
||||
|
||||
reclaim_target = mblock1.info.trunk_total_count - mblock1.info.trunk_used_count;
|
||||
reclaim_target -= 2;
|
||||
fast_mblock_reclaim(&mblock1, reclaim_target, &reclaim_count, NULL);
|
||||
fast_mblock_reclaim(&mblock2, reclaim_target, &reclaim_count, NULL);
|
||||
|
||||
fast_mblock_manager_stat_print(false);
|
||||
|
||||
sleep(31);
|
||||
obj1 = fast_mblock_alloc_object(&mblock1);
|
||||
obj2 = fast_mblock_alloc_object(&mblock1);
|
||||
|
||||
reclaim_target = (mblock1.info.trunk_total_count - mblock1.info.trunk_used_count);
|
||||
//reclaim_target = 1;
|
||||
fast_mblock_reclaim(&mblock1, reclaim_target, &reclaim_count, NULL);
|
||||
fast_mblock_reclaim(&mblock2, reclaim_target, &reclaim_count, NULL);
|
||||
|
||||
fast_mblock_manager_stat_print(false);
|
||||
|
||||
obj1 = fast_mblock_alloc_object(&mblock1);
|
||||
obj2 = fast_mblock_alloc_object(&mblock2);
|
||||
|
||||
fast_mblock_manager_stat_print(false);
|
||||
|
||||
fast_mblock_destroy(&mblock1);
|
||||
fast_mblock_destroy(&mblock2);
|
||||
fast_mblock_manager_stat_print(false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue