support get local mac addresses

pull/5/head
yuqing 2016-01-12 10:56:07 +08:00
parent 5d130c1608
commit 1c6a73d4f3
6 changed files with 365 additions and 14 deletions

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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:

158
src/tests/test_mblock.c Normal file
View File

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