📄 hypervisor.c
字号:
hypervisor_cmd_t *cmd; if (!(module = hypervisor_find_module(mod_name))) { hypervisor_send_reply(conn,HSC_ERR_UNK_MODULE,1,"Unknown module '%s'", mod_name); return(-1); } if (!(cmd = hypervisor_find_cmd(module,cmd_name))) { hypervisor_send_reply(conn,HSC_ERR_UNK_CMD,1,"Unknown command '%s'", cmd_name); return(-1); } if ((argc < cmd->min_param) || (argc > cmd->max_param)) { hypervisor_send_reply(conn,HSC_ERR_BAD_PARAM,1, "Bad number of parameters (%d with min/max=%d/%d)", argc,cmd->min_param,cmd->max_param); return(-1); } conn->cur_module = module; return(cmd->handler(conn,argc,argv));}/* Thread for servicing connections */static void *hypervisor_thread(void *arg){ hypervisor_conn_t *conn = arg; char buffer[512],**tokens; parser_context_t ctx; int res; tokens = NULL; parser_context_init(&ctx); while(conn->active) { if (!fgets(buffer,sizeof(buffer),conn->in)) break; if (!*buffer) continue; /* Tokenize command line */ res = parser_scan_buffer(&ctx,buffer,strlen(buffer)); if (res != 0) { tokens = NULL; if (ctx.error != 0) { hypervisor_send_reply(conn,HSC_ERR_PARSING,1,"Parse error: %s", parser_strerror(&ctx)); goto free_tokens; } if (ctx.tok_count < 2) { hypervisor_send_reply(conn,HSC_ERR_PARSING,1, "At least a module and a command " "must be specified"); goto free_tokens; } /* Map token list to an array */ tokens = parser_map_array(&ctx); if (!tokens) { hypervisor_send_reply(conn,HSC_ERR_PARSING,1,"No memory"); goto free_tokens; } /* Execute command */ //m_log("hypervisor_exec","%s\n",buffer); hypervisor_exec_cmd(conn,tokens[0],tokens[1],ctx. tok_count-2,&tokens[2]); free_tokens: free(tokens); tokens = NULL; parser_context_free(&ctx); } } free(tokens); parser_context_free(&ctx); return NULL;}static void sigpipe_handler(int sig){ printf("SIGPIPE received.\n");}/* Initialize hypervisor */int hypervisor_init(void){ hypervisor_module_t *module; module = hypervisor_register_module("hypervisor",NULL); assert(module != NULL); hypervisor_register_cmd_array(module,hypervisor_cmd_array); return(0);}/* Remove a connection from the list */static void hypervisor_remove_conn(hypervisor_conn_t *conn){ if (conn->pprev != NULL) { if (conn->next) conn->next->pprev = conn->pprev; *(conn->pprev) = conn->next; }}/* Close a connection */static void hypervisor_close_conn(hypervisor_conn_t *conn){ if (conn != NULL) { conn->active = FALSE; shutdown(conn->client_fd,2); pthread_join(conn->tid,NULL); fclose(conn->in); fclose(conn->out); shutdown(conn->client_fd,2); close(conn->client_fd); hypervisor_remove_conn(conn); free(conn); }}/* Close connections (dead or all) */static void hypervisor_close_conn_list(int dead_status){ hypervisor_conn_t *conn,*next; for(conn=hypervisor_conn_list;conn;conn=next) { next = conn->next; if (dead_status && conn->active) continue; hypervisor_close_conn(conn); }}/* Add a new connection to the list */static void hypervisor_add_conn(hypervisor_conn_t *conn){ conn->next = hypervisor_conn_list; conn->pprev = &hypervisor_conn_list; if (hypervisor_conn_list != NULL) hypervisor_conn_list->pprev = &conn->next; hypervisor_conn_list = conn;}/* Create a new connection */static hypervisor_conn_t *hypervisor_create_conn(int client_fd){ hypervisor_conn_t *conn; if (!(conn = malloc(sizeof(*conn)))) goto err_malloc; memset(conn,0,sizeof(*conn)); conn->active = TRUE; conn->client_fd = client_fd; /* Open input buffered stream */ if (!(conn->in = fdopen(client_fd,"r"))) { perror("hypervisor_create_conn: fdopen/in"); goto err_fd_in; } /* Open output buffered stream */ if (!(conn->out = fdopen(client_fd,"w"))) { perror("hypervisor_create_conn: fdopen/out"); goto err_fd_out; } /* Set line buffering */ setlinebuf(conn->in); setlinebuf(conn->out); /* Create the managing thread */ if (pthread_create(&conn->tid,NULL,hypervisor_thread,conn) != 0) goto err_thread; /* Add it to the connection list */ hypervisor_add_conn(conn); return conn; err_thread: fclose(conn->out); err_fd_out: fclose(conn->in); err_fd_in: free(conn); err_malloc: return NULL;}/* Stop hypervisor from sighandler */int hypervisor_stopsig(void){ hypervisor_running = FALSE; return(0);}/* Hypervisor TCP server */int hypervisor_tcp_server(char *ip_addr,int tcp_port){ int fd_array[HYPERVISOR_MAX_FD]; struct sockaddr_storage remote_addr; socklen_t remote_len; int i,res,clnt,fd_count,fd_max; struct timeval tv; fd_set fds; /* Initialize all hypervisor modules */ hypervisor_init(); hypervisor_nio_init(); hypervisor_nio_bridge_init(); hypervisor_frsw_init(); hypervisor_atmsw_init(); hypervisor_atm_bridge_init(); hypervisor_ethsw_init(); hypervisor_vm_init(); hypervisor_vm_debug_init(); hypervisor_store_init(); signal(SIGPIPE,sigpipe_handler); if (!tcp_port) tcp_port = HYPERVISOR_TCP_PORT; fd_count = ip_listen(ip_addr,tcp_port,SOCK_STREAM, HYPERVISOR_MAX_FD,fd_array); if (fd_count <= 0) { fprintf(stderr,"Hypervisor: unable to create TCP sockets.\n"); return(-1); } /* Start accepting connections */ printf("Hypervisor TCP control server started (port %d).\n",tcp_port); hypervisor_running = TRUE; while(hypervisor_running) { FD_ZERO(&fds); fd_max = -1; for(i=0;i<fd_count;i++) if (fd_array[i] != -1) { FD_SET(fd_array[i],&fds); if (fd_array[i] > fd_max) fd_max = fd_array[i]; } /* Wait for incoming connections */ tv.tv_sec = 0; tv.tv_usec = 500 * 1000; /* 500 ms */ res = select(fd_max+1,&fds,NULL,NULL,&tv); if (res == -1) { if (errno == EINTR) continue; else perror("hypervisor_tcp_server: select"); } /* Accept connections on signaled sockets */ for(i=0;i<fd_count;i++) { if (fd_array[i] == -1) continue; if (!FD_ISSET(fd_array[i],&fds)) continue; remote_len = sizeof(remote_addr); clnt = accept(fd_array[i],(struct sockaddr *)&remote_addr, &remote_len); if (clnt < 0) { perror("hypervisor_tcp_server: accept"); continue; } /* create a new connection and start a thread to handle it */ if (!hypervisor_create_conn(clnt)) { fprintf(stderr,"hypervisor_tcp_server: unable to create new " "connection for FD %d\n",clnt); close(clnt); } } /* Walk through the connection list to eliminate dead connections */ hypervisor_close_conn_list(TRUE); } /* Close all control sockets */ printf("Hypervisor: closing control sockets.\n"); for(i=0;i<fd_count;i++) { if (fd_array[i] != -1) { shutdown(fd_array[i],2); close(fd_array[i]); } } /* Close all remote client connections */ printf("Hypervisor: closing remote client connections.\n"); hypervisor_close_conn_list(FALSE); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -