1 |
/* |
/* |
2 |
* Cisco 7200 (Predator) simulation platform. |
* Cisco router simulation platform. |
3 |
* Copyright (c) 2006 Christophe Fillot (cf@utc.fr) |
* Copyright (c) 2006 Christophe Fillot (cf@utc.fr) |
4 |
* |
* |
5 |
* Hypervisor routines. |
* Hypervisor routines. |
32 |
#include "parser.h" |
#include "parser.h" |
33 |
#include "net.h" |
#include "net.h" |
34 |
#include "registry.h" |
#include "registry.h" |
35 |
#include "mips64.h" |
#include "cpu.h" |
36 |
|
#include "vm.h" |
37 |
#include "dynamips.h" |
#include "dynamips.h" |
38 |
#include "dev_c7200.h" |
#include "dev_c7200.h" |
39 |
#include "dev_c3600.h" |
#include "dev_c3600.h" |
40 |
|
#include "dev_c2691.h" |
41 |
|
#include "dev_c3725.h" |
42 |
|
#include "dev_c3745.h" |
43 |
|
#include "dev_c2600.h" |
44 |
|
#include "dev_c1700.h" |
45 |
#include "hypervisor.h" |
#include "hypervisor.h" |
46 |
#include "net_io.h" |
#include "net_io.h" |
47 |
#include "net_io_bridge.h" |
#include "net_io_bridge.h" |
64 |
return(0); |
return(0); |
65 |
} |
} |
66 |
|
|
67 |
|
/* Parser test */ |
68 |
|
static int cmd_parser_test(hypervisor_conn_t *conn,int argc,char *argv[]) |
69 |
|
{ |
70 |
|
int i; |
71 |
|
|
72 |
|
for(i=0;i<argc;i++) |
73 |
|
hypervisor_send_reply(conn,HSC_INFO_MSG,0, |
74 |
|
"arg %d (len %u): \"%s\"", |
75 |
|
i,strlen(argv[i]),argv[i]); |
76 |
|
|
77 |
|
hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); |
78 |
|
return(0); |
79 |
|
} |
80 |
|
|
81 |
/* Show hypervisor module list */ |
/* Show hypervisor module list */ |
82 |
static int cmd_mod_list(hypervisor_conn_t *conn,int argc,char *argv[]) |
static int cmd_mod_list(hypervisor_conn_t *conn,int argc,char *argv[]) |
83 |
{ |
{ |
137 |
frsw_save_config_all(fd); |
frsw_save_config_all(fd); |
138 |
atmsw_save_config_all(fd); |
atmsw_save_config_all(fd); |
139 |
netio_bridge_save_config_all(fd); |
netio_bridge_save_config_all(fd); |
140 |
c7200_save_config_all(fd); |
vm_save_config_all(fd); |
|
c3600_save_config_all(fd); |
|
141 |
|
|
142 |
hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); |
hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); |
143 |
return(0); |
return(0); |
170 |
/* Hypervisor commands */ |
/* Hypervisor commands */ |
171 |
static hypervisor_cmd_t hypervisor_cmd_array[] = { |
static hypervisor_cmd_t hypervisor_cmd_array[] = { |
172 |
{ "version", 0, 0, cmd_version, NULL }, |
{ "version", 0, 0, cmd_version, NULL }, |
173 |
|
{ "parser_test", 0, 10, cmd_parser_test, NULL }, |
174 |
{ "module_list", 0, 0, cmd_mod_list, NULL }, |
{ "module_list", 0, 0, cmd_mod_list, NULL }, |
175 |
{ "cmd_list", 1, 1, cmd_modcmd_list, NULL }, |
{ "cmd_list", 1, 1, cmd_modcmd_list, NULL }, |
176 |
{ "working_dir", 1, 1, cmd_set_working_dir, NULL }, |
{ "working_dir", 1, 1, cmd_set_working_dir, NULL }, |
239 |
} |
} |
240 |
|
|
241 |
/* Find a VM in the registry */ |
/* Find a VM in the registry */ |
242 |
void *hypervisor_find_vm(hypervisor_conn_t *conn,char *name,int vm_type) |
void *hypervisor_find_vm(hypervisor_conn_t *conn,char *name) |
243 |
{ |
{ |
244 |
|
vm_platform_t *platform = conn->cur_module->opt; |
245 |
vm_instance_t *vm; |
vm_instance_t *vm; |
246 |
|
|
247 |
if (!(vm = vm_acquire(name))) { |
if (!(vm = vm_acquire(name))) { |
250 |
return NULL; |
return NULL; |
251 |
} |
} |
252 |
|
|
253 |
if (vm->type != vm_type) { |
if (vm->platform != platform) { |
254 |
vm_release(vm); |
vm_release(vm); |
255 |
hypervisor_send_reply(conn,HSC_ERR_BAD_OBJ,1, |
hypervisor_send_reply(conn,HSC_ERR_BAD_OBJ,1, |
256 |
"VM '%s' is not a VM type %d", |
"VM '%s' is not a VM type %s", |
257 |
name,vm_type); |
name,platform->name); |
258 |
return NULL; |
return NULL; |
259 |
} |
} |
260 |
|
|
262 |
} |
} |
263 |
|
|
264 |
/* Register a module */ |
/* Register a module */ |
265 |
hypervisor_module_t *hypervisor_register_module(char *name) |
hypervisor_module_t *hypervisor_register_module(char *name,void *opt) |
266 |
{ |
{ |
267 |
hypervisor_module_t *m; |
hypervisor_module_t *m; |
268 |
|
|
277 |
} |
} |
278 |
|
|
279 |
m->name = name; |
m->name = name; |
280 |
|
m->opt = opt; |
281 |
m->cmd_list = NULL; |
m->cmd_list = NULL; |
282 |
|
|
283 |
m->next = module_list; |
m->next = module_list; |
340 |
return(-1); |
return(-1); |
341 |
} |
} |
342 |
|
|
343 |
|
conn->cur_module = module; |
344 |
|
|
345 |
return(cmd->handler(conn,argc,argv)); |
return(cmd->handler(conn,argc,argv)); |
346 |
} |
} |
347 |
|
|
349 |
static void *hypervisor_thread(void *arg) |
static void *hypervisor_thread(void *arg) |
350 |
{ |
{ |
351 |
hypervisor_conn_t *conn = arg; |
hypervisor_conn_t *conn = arg; |
352 |
char buffer[4096],**tokens; |
char buffer[512],**tokens; |
353 |
parser_token_t *tok_list; |
parser_context_t ctx; |
354 |
int res,tok_count; |
int res; |
355 |
|
|
356 |
|
tokens = NULL; |
357 |
|
parser_context_init(&ctx); |
358 |
|
|
359 |
while(conn->active) { |
while(conn->active) { |
360 |
if (!m_fgets(buffer,sizeof(buffer),conn->in)) |
if (!fgets(buffer,sizeof(buffer),conn->in)) |
361 |
break; |
break; |
362 |
|
|
363 |
if (!*buffer) |
if (!*buffer) |
364 |
continue; |
continue; |
365 |
|
|
366 |
/* Tokenize command line */ |
/* Tokenize command line */ |
367 |
tokens = NULL; |
res = parser_scan_buffer(&ctx,buffer,strlen(buffer)); |
|
res = parser_tokenize(buffer,&tok_list,&tok_count); |
|
368 |
|
|
369 |
if (res != 0) { |
if (res != 0) { |
370 |
hypervisor_send_reply(conn,HSC_ERR_PARSING,1,"Parse error: %s", |
tokens = NULL; |
|
parser_strerror(res)); |
|
|
continue; |
|
|
} |
|
371 |
|
|
372 |
if (tok_count < 2) { |
if (ctx.error != 0) { |
373 |
hypervisor_send_reply(conn,HSC_ERR_PARSING,1, |
hypervisor_send_reply(conn,HSC_ERR_PARSING,1,"Parse error: %s", |
374 |
"At least a module and a command " |
parser_strerror(&ctx)); |
375 |
"must be specified"); |
goto free_tokens; |
376 |
goto free_tokens; |
} |
377 |
} |
|
378 |
|
if (ctx.tok_count < 2) { |
379 |
|
hypervisor_send_reply(conn,HSC_ERR_PARSING,1, |
380 |
|
"At least a module and a command " |
381 |
|
"must be specified"); |
382 |
|
goto free_tokens; |
383 |
|
} |
384 |
|
|
385 |
/* Map token list to an array */ |
/* Map token list to an array */ |
386 |
tokens = parser_map_array(tok_list,tok_count); |
tokens = parser_map_array(&ctx); |
387 |
|
|
388 |
if (!tokens) { |
if (!tokens) { |
389 |
hypervisor_send_reply(conn,HSC_ERR_PARSING,1,"No memory"); |
hypervisor_send_reply(conn,HSC_ERR_PARSING,1,"No memory"); |
390 |
goto free_tokens; |
goto free_tokens; |
391 |
} |
} |
392 |
|
|
393 |
/* Execute command */ |
/* Execute command */ |
394 |
m_log("hypervisor_exec","%s\n",buffer); |
//m_log("hypervisor_exec","%s\n",buffer); |
395 |
hypervisor_exec_cmd(conn,tokens[0],tokens[1],tok_count-2,&tokens[2]); |
hypervisor_exec_cmd(conn,tokens[0],tokens[1],ctx. |
396 |
|
tok_count-2,&tokens[2]); |
397 |
|
|
398 |
free_tokens: |
free_tokens: |
399 |
free(tokens); |
free(tokens); |
400 |
parser_free_tokens(tok_list); |
tokens = NULL; |
401 |
|
parser_context_free(&ctx); |
402 |
|
} |
403 |
} |
} |
404 |
|
|
405 |
|
free(tokens); |
406 |
|
parser_context_free(&ctx); |
407 |
return NULL; |
return NULL; |
408 |
} |
} |
409 |
|
|
417 |
{ |
{ |
418 |
hypervisor_module_t *module; |
hypervisor_module_t *module; |
419 |
|
|
420 |
module = hypervisor_register_module("hypervisor"); |
module = hypervisor_register_module("hypervisor",NULL); |
421 |
assert(module != NULL); |
assert(module != NULL); |
422 |
|
|
423 |
hypervisor_register_cmd_array(module,hypervisor_cmd_array); |
hypervisor_register_cmd_array(module,hypervisor_cmd_array); |
535 |
} |
} |
536 |
|
|
537 |
/* Hypervisor TCP server */ |
/* Hypervisor TCP server */ |
538 |
int hypervisor_tcp_server(int tcp_port) |
int hypervisor_tcp_server(char *ip_addr,int tcp_port) |
539 |
{ |
{ |
540 |
int fd_array[HYPERVISOR_MAX_FD]; |
int fd_array[HYPERVISOR_MAX_FD]; |
541 |
struct sockaddr_storage remote_addr; |
struct sockaddr_storage remote_addr; |
552 |
hypervisor_atmsw_init(); |
hypervisor_atmsw_init(); |
553 |
hypervisor_ethsw_init(); |
hypervisor_ethsw_init(); |
554 |
hypervisor_vm_init(); |
hypervisor_vm_init(); |
555 |
hypervisor_c7200_init(); |
hypervisor_vm_debug_init(); |
|
hypervisor_c3600_init(); |
|
556 |
|
|
557 |
signal(SIGPIPE,sigpipe_handler); |
signal(SIGPIPE,sigpipe_handler); |
558 |
|
|
559 |
if (!tcp_port) |
if (!tcp_port) |
560 |
tcp_port = HYPERVISOR_TCP_PORT; |
tcp_port = HYPERVISOR_TCP_PORT; |
561 |
|
|
562 |
fd_count = ip_listen(tcp_port,SOCK_STREAM,HYPERVISOR_MAX_FD,fd_array); |
fd_count = ip_listen(ip_addr,tcp_port,SOCK_STREAM, |
563 |
|
HYPERVISOR_MAX_FD,fd_array); |
564 |
|
|
565 |
if (fd_count <= 0) { |
if (fd_count <= 0) { |
566 |
fprintf(stderr,"Hypervisor: unable to create TCP sockets.\n"); |
fprintf(stderr,"Hypervisor: unable to create TCP sockets.\n"); |
568 |
} |
} |
569 |
|
|
570 |
/* Start accepting connections */ |
/* Start accepting connections */ |
571 |
printf("Hypervisor TCP control server started.\n"); |
printf("Hypervisor TCP control server started (port %d).\n",tcp_port); |
572 |
hypervisor_running = TRUE; |
hypervisor_running = TRUE; |
573 |
|
|
574 |
while(hypervisor_running) { |
while(hypervisor_running) { |