前提:
已经知道虚机的配置和物理机剩余的资源,分别用CPU核数和内存大小(MB)来表示,比如VM的配置文件为:
cat vm.txt
192.168.1.100 cpu 内存
192.168.1.101 cpu 内存
192.168.1.103 cpu 内存
要把这些vm生产到一批物理机上,这些物理机归属不同的类型,或者集群,用colo标识,物理机资源文件如下:
colo1 物理机1 可用cpu 可用内存
colo2 物理机2 可用cpu 可用内存
目标:把vm生产到这些物理机上面,并且使得每台物理机有一定的cpu和内存预留下来,算法如下:
#include
#include
#include
typedef struct _vm
{
char ip[16];
int cpu;
int mem;
void * next;
}vm_t;
vm_t g_vmlist[5000];
int g_vmnum = 0;
typedef struct _nc
{
char name[64];
int cpu;
int mem;
vm_t* vmlist;
int vm_num;
void* next;
}nc_t;
typedef struct _colo
{
char name [64];
nc_t* nc_list;
int nc_num;
}colo_t;
#define COLO_NUM 10
typedef struct _region
{
colo_t clist [COLO_NUM];
int colo_num;
}region_t;
region_t g_reg;
int load_vm(const char* fname);
int load_nc(const char* fname);
int assign_vm(void);
void print_res(void);
int main (int argc, char* argv[])
{
load_vm(“vm.txt”);
load_nc (“resource.txt”);
assign_vm();
print_res();
return 0;
}
int load_vm(const char* fname)
{
FILE * fp = fopen (fname, “r”);
if (fp == NULL)
{
printf (“can not find file ‘%s’ to op\nn”, fname);
return 0;
}
char szline[1024] = {0};
while (fgets(szline, 1024, fp))
{
int cpu = 0,mem=0;
char ip[16] = {0};
if (sscanf(szline, “%s %d %d”, ip, &cpu, &mem) != 3)
{
printf (“error data:%s”, szline);
continue;
}
memset (g_vmlist + g_vmnum, 0, sizeof(vm_t));
vm_t * pv = g_vmlist + g_vmnum;
strcpy(pv->ip, ip);
pv->cpu = cpu;
pv->mem = mem;
g_vmnum++;
//printf (“%s”,szline);
}
fclose (fp);
//printf (“%u vm(s) loaded\n”, g_vmnum);
return g_vmnum;
}
void insert_nc (const char* nc,const char* colo, int cpu, int mem);
int load_nc(const char* fname)
{
FILE * fp = fopen (fname, “r”);
if (fp == NULL)
{
printf (“can not find file ‘%s’ to op\nn”, fname);
return 0;
}
char szline[1024] = {0};
g_reg.colo_num = 0;
int i = 0;
for (i = 0; i < COLO_NUM; i++)
{
memset (g_reg.clist + i, 0, sizeof(colo_t));
}
while (fgets(szline, 1024, fp))
{
char colo[8] = {0},nc[64] = {0};
int cpu = 0, mem = 0;
if (sscanf(szline, "%s %s %d %d", colo,nc,&cpu,&mem) != 4)
{
printf("read bad data:%s", szline);
continue;
}
insert_nc (nc, colo, cpu, mem);
}
fclose(fp);
return g_reg.colo_num;
}
void insert_nc (const char* strnc,const char* colo, int cpu, int mem)
{
nc_t nc;
memset (&nc,0,sizeof(nc));
strcpy (nc.name, strnc);
nc.cpu = cpu;
nc.mem = mem;
nc.vmlist = NULL;
nc.vm_num = 0;
nc.next = NULL;
int i = 0;
int pos = -1;
for (i = 0; i < g_reg.colo_num; i++)
{
if (strcmp(colo, g_reg.clist[i].name) == 0)
{
pos = i;
break;
}
}
if (pos == -1)
{
pos = i;
strcpy (g_reg.clist[pos].name, colo);
g_reg.clist[pos].nc_list = NULL;
g_reg.clist[pos].nc_num = 0;
g_reg.colo_num++;
}
colo_t * pc = g_reg.clist + pos;
nc_t * pn = (nc_t*) malloc(sizeof(nc_t));
memset (pn, 0, sizeof(nc_t));
memcpy(pn, &nc, sizeof(nc_t));
if (pc->nc_list == NULL)
{
pc->nc_list = pn;
pc->nc_num = 1;
}else
{
pn->next = pc->nc_list;
pc->nc_list = pn;
pc->nc_num++;
}
//printf (“adding to colo ‘%s (%d)’,total nc: %u %s %u %u\n”, pc->name, pos, pc->nc_num, pn->name, pn->cpu, pn->mem);
}
const nc_t * ins_vm(vm_t * pv, int pos);
int assign_vm(void)
{
int i = 0;
int pos = 0;
for (i = 0; i < g_vmnum; )
{
vm_t * pv = g_vmlist + i;
pv->next = NULL;
const nc_t * ret = ins_vm (pv, pos);
if (ret == NULL)
{
//printf(“Migrating %s====>%d %d %s failed\n”, pv->ip, pv->cpu, pv->mem, g_reg.clist[pos].name);
}
else
{
//printf(“Migrating %s %u %u ==> %s %u %u success \n”, pv->ip, pv->cpu, pv->mem, ret->name, ret->cpu, ret->mem);
i++;
}
pos = (pos + 1) % g_reg.colo_num;
}
return 1;
}
const nc_t * ins_vm(vm_t * pv, int pos)
{
colo_t * pc = g_reg.clist + pos;
nc_t * pn = pc->nc_list;
nc_t * ret = NULL;
while (pn)
{
int acpu = 4;
if (pv->cpu >= acpu) acpu = pv->cpu;
if ((pn->cpu – pv->cpu >= acpu) && (pn->mem – pv->mem >= pv->mem))
{
pn->cpu -= pv->cpu;
pn->mem -= pv->mem;
ret = pn;
if (pn->vmlist == NULL)
{
pn->vmlist = pv;
pn->vm_num = 1;
}else
{
pv->next = pn->vmlist;
pn->vmlist = pv;
pn->vm_num++;
}
break;
}
//printf (“%s %u %u\n”, pn->name, pn->cpu, pn->mem);
pn = pn->next;
}
return ret;
}
void print_res(void)
{
int i = 0;
for (i = 0; i < g_reg.colo_num; i++)
{
colo_t * pc = g_reg.clist + i;
nc_t * pn = pc->nc_list;
while (pn)
{
vm_t * pv = pn->vmlist;
while (pv)
{
printf (“%s %d %d => %s %s %d %d\n”, pv->ip, pv->cpu, pv->mem, pc->name, pn->name,pn->cpu, pn->mem);
pv = pv->next;
}
pn = pn->next;
}
}
}